Cómo forzar a GridView a generar celdas cuadradas en Android

¿Cómo puedo forzar un GridView de Android para generar células cuadradas (la altura de la celda es igual al ancho de la celda) GridView tiene 10 * 9 celdas y la aplicación debe soportar varias pantallas!

Utilicé un diseño lineal:

row_grid.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="0dp" > <ImageView android:id="@+id/item_image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/ic_launcher" > </ImageView> </LinearLayout> 

y GridView: activity_main.xml

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/katy" > <GridView android:id="@+id/gridView1" android:layout_width="match_parent" android:layout_height="match_parent" android:horizontalSpacing="0dp" android:numColumns="4" android:stretchMode="columnWidth" android:verticalSpacing="0dp" > </GridView> </RelativeLayout> 

Cada celda de GridView contiene una imagen que tiene el mismo ancho y la misma altura. las imágenes son más grandes que las células y deben estirarse para encajar en las células. Introduzca aquí la descripción de la imagen

En primer lugar, va a querer crear una clase de vista personalizada que puede utilizar en lugar del LinearLayout predeterminado que está utilizando. A continuación, desea anular la llamada OnMeasure de la vista y forzarla a que sea cuadrada:

 public class GridViewItem extends ImageView { public GridViewItem(Context context) { super(context); } public GridViewItem(Context context, AttributeSet attrs) { super(context, attrs); } public GridViewItem(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width } } 

A continuación, puede cambiar el archivo row_grid.xml a:

 <path.to.item.GridViewItem xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item_image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@drawable/ic_launcher" > </path.to.item.GridViewItem> 

Sólo asegúrese de cambiar "path.to.item" al paquete donde reside su clase GridViewItem.java.

También he eliminado su padre LinearLayout ya que no estaba haciendo nada para usted allí.

Editar:

También cambió scaleType de fitXY a centerCrop para que su imagen no se estira y mantiene su relación de aspecto. Y, siempre y cuando sea una imagen cuadrada, nada debe ser recortado, independientemente.

Puede anular su disposición lineal

 public class MyLinearLayout extends LinearLayout { public MyLinearLayout(Context context) { super(context); } public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); // This is the key that will make the height equivalent to its width } } 

luego usarlo en el archivo item_grid.xml

 <?xml version="1.0" encoding="utf-8"?> <com.example.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/item_grid" android:layout_margin="2dp" android:padding="3dp" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Category Name" android:textStyle="bold" android:textColor="@color/colorPrimary" android:id="@+id/tvCategoryName" /> </com.example.MyLinearLayout> 

Funciona muy bien, gracias! Una pequeña mejora que requería siempre sería elegir el valor más pequeño, para evitar superar la pantalla:

 @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(heightMeasureSpec < widthMeasureSpec) { super.onMeasure(heightMeasureSpec, heightMeasureSpec); } else if(widthMeasureSpec < heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } 

Sólo asegúrese de que sus imágenes son cuadradas. Y hacer el contenedor wrap_content.

  • ¿Cómo manejar ** Grid View ** en el cambio de configuración?
  • Android cómo cambiar el color de resaltado de gridview?
  • Cómo vaciar una gridview en Android?
  • Cómo configurar la altura del ancho de la imagen en función del tamaño de la pantalla en gridview
  • Android GridView Elemento seleccionado Fondo
  • Cómo obtener GridView desplazarse a la parte superior con el teclado en Android TV
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.