propiedades - menu gridview android
Hacer cuadrados los elementos de GridView (12)
¡Esto funcionó para mí!
Si eres como yo y no puedes usar getRequestedColumnWidth () porque tu minSdk es menor que 16, te sugiero esta opción.
en tu fragmento:
DisplayMetrics dm = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); int size = dm.widthPixels / nbColumns; CustomAdapter adapter = new CustomAdapter(list, size, getActivity());
en su adaptador (en getView (int position, View convertView, ViewGroup parent))
v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));
fragment.xml:
<GridView android:id="@+id/gridView" android:layout_width="match_parent" android:layout_height="match_parent" android:horizontalSpacing="3dp" android:verticalSpacing="3dp" android:numColumns="4" android:stretchMode="columnWidth" />
custom_item.xml: (por ejemplo)
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/picture" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" />
Espero que ayude a alguien!
Me gustaría que los elementos de mi GridView
sean cuadrados. Hay 2 columnas y el ancho de los elementos es fill_parent
(por ejemplo, ocupan tanto espacio horizontal como sea posible. Los elementos son vistas personalizadas.
¿Cómo hago para que la altura de los artículos sea igual a su ancho variable?
En la línea de la respuesta de @ Gregory, tuve que envolver mi imagen en LinearLayout para evitar que GridView manipule sus dimensiones desde el cuadrado. Tenga en cuenta que el LinearLayout externo debe configurarse para tener la dimensión de la imagen, y el ancho de la columna GridView debe ser el ancho de la imagen MÁS cualquier margen. Por ejemplo:
<!-- LinearLayout wrapper necessary to wrap image button in order to keep square;
otherwise, the grid view distorts it into rectangle.
also, margin top and right allows the indicator overlay to extend top and right.
NB: grid width is set in filter_icon_page.xml, and must correspond to size + margin
-->
<LinearLayout
android:id="@+id/sport_icon_lay"
android:layout_width="60dp"
android:layout_height="60dp"
android:orientation="vertical"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp"
>
<ImageButton
android:id="@+id/sport_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:maxHeight="60dp"
android:maxWidth="60dp"
android:scaleType="fitCenter"
/>
</LinearLayout>
y el GridView como:
<GridView
android:id="@+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:columnWidth="66dp"
android:numColumns="auto_fit"
android:verticalSpacing="25dp"
android:horizontalSpacing="24dp"
android:stretchMode="spacingWidth"
/>
En tu actividad
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
valX = displaymetrics.widthPixels/columns_number;
en CustomAdapter de GridView
v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, YourActivity.valX));
Esto es lo que estoy haciendo para mostrar celdas cuadradas en un GridView. No estoy seguro si quieres celdas cuadradas o algo más.
GridView grid = new GridView( this );
grid.setColumnWidth( UIScheme.cellSize );
grid.setVerticalSpacing( UIScheme.gap );
grid.setStretchMode( GridView.STRETCH_COLUMN_WIDTH );
grid.setNumColumns( GridView.AUTO_FIT );
Y luego, la vista que estoy creando para cada celda, tengo que hacer lo siguiente con ella:
cell.setLayoutParams( new GridView.LayoutParams(iconSize, iconSize) );
Hay una solución más simple cuando se estiran las columnas de GridView. Simplemente anule el onMeasure del diseño del elemento GridView con ...
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
No estoy seguro de que esto sea posible con los widgets actuales. Su mejor opción podría ser colocar su vista personalizada en un "SquareView" personalizado. Esta vista solo puede contener 1 vista secundaria y forzar la altura para igualar el ancho cuando se llama a su método onLayout.
Nunca intenté hacer algo así, pero creo que no debería ser demasiado difícil. Una solución alternativa (y tal vez un poco más fácil) podría ser subclasificar el diseño raíz de su vista personalizada (como, si es un LinearLayout, hacer un SquareLinearLayout), y usarlo como un contenedor en su lugar.
editar: Aquí hay una implementación básica que parece funcionar para mí:
package com.mantano.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
public class SquareView extends ViewGroup {
public SquareView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int l, int u, int r, int d) {
getChildAt(0).layout(0, 0, r-l, d-u); // Layout with max size
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
View child = getChildAt(0);
child.measure(widthMeasureSpec, widthMeasureSpec);
int width = resolveSize(child.getMeasuredWidth(), widthMeasureSpec);
child.measure(width, width); // 2nd pass with the correct size
setMeasuredDimension(width, width);
}
}
Está diseñado para tener un hijo único, pero ignoré todos los controles por simplicidad. La idea básica es medir el niño con los parámetros de ancho / alto establecidos por GridView (en mi caso, usa numColumns = 4 para calcular el ancho), y luego hacer un segundo pase con las dimensiones finales, con altura = ancho. .. El diseño es simplemente un diseño simple, que presenta el niño único en (0, 0) con las dimensiones deseadas (derecha-izquierda, abajo-arriba).
Y aquí está el XML utilizado para los artículos GridView:
<?xml version="1.0" encoding="utf-8"?>
<com.mantano.widget.SquareView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<LinearLayout android:id="@+id/item" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="horizontal"
android:gravity="center">
<TextView android:id="@+id/text" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Hello world" />
</LinearLayout>
</com.mantano.widget.SquareView>
Utilicé LinearLayout dentro de SquareView para que pueda gestionar todas las posibilidades de gravedad, los márgenes, etc.
No estoy seguro de qué tan bien (o malo) este widget reaccionaría a la orientación y los cambios de dimensión, pero parece funcionar correctamente.
No sé si es la mejor manera, pero lo logro haciendo que mi vista personalizada anule onSizeChanged de esa manera:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (getLayoutParams() != null && w != h) {
getLayoutParams().height = w;
setLayoutParams(getLayoutParams());
}
}
¡Utilizo esta vista personalizada dentro de LinearLayout y GridView y en ambos muestra square!
O si desea extender una Vista simplemente haga algo realmente simple como:
public class SquareImageView extends ImageView
{
public SquareImageView(final Context context)
{
super(context);
}
public SquareImageView(final Context context, final AttributeSet attrs)
{
super(context, attrs);
}
public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
final int width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
setMeasuredDimension(width, width);
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh)
{
super.onSizeChanged(w, w, oldw, oldh);
}
}
Vale la pena señalar que no es necesario super.onMeasure()
. onMeasured
requisito de onMeasured
es que debes llamar a setMeasuredDimension
.
Según la respuesta de SteveBorkman , que es API 16+:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
GridView grid = (GridView)parent;
int size = grid.getColumnWidth();
if (convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.your_item, null);
convertView.setLayoutParams(new GridView.LayoutParams(size, size));
}
//Modify your convertView here
return convertView;
}
Termina siendo bastante fácil obtener el elemento cuadriculado.
En su método "GetView" de su adaptador de red, solo haga lo siguiente:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
GridView grid = (GridView)parent;
int size = grid.getRequestedColumnWidth();
TextView text = new TextView(getContext());
text.setLayoutParams(new GridView.LayoutParams(size, size));
// Whatever else you need to set on your view
return text;
}
Tratar
<GridView
...
android:stretchMode="columnWidth" />
También puedes jugar con otros modos
si establece un número estático de columnas en el xml, puede tomar el ancho de la vista y dividirlo por el número de columnas.
Si está usando auto_fit
, va a ser un poco complicado obtener el conteo de la columna (no hay método getColumnCount ()), por cierto, this pregunta debería ayudarlo de alguna manera.
este es el código que estoy usando en el getView(...)
del adaptador con un número fijo de columnas:
item_side = mFragment.holder.grid.getWidth() / N_COL;
v.getLayoutParams().height = item_side;
v.getLayoutParams().width = item_side;