Comment puis-je forcer un Android GridView pour générer des cellules carrées (hauteur de cellule égale à la largeur de cellule) GridView a 10 * 9 cellules et l'application doit prendre en charge plusieurs écrans!
J'ai utilisé une disposition linéaire:
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>
et 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>
Chaque cellule de GridView contient une image qui a la même largeur et la même hauteur. les images sont plus grandes que les cellules et doivent s'étirer pour tenir dans les cellules.
Tout d'abord, vous allez vouloir créer une classe View personnalisée que vous pouvez utiliser à la place du LinearLayout par défaut que vous utilisez. Ensuite, vous voulez remplacer l'appel onMeasure de la vue et le forcer à être carré:
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
}
}
Vous pouvez ensuite modifier votre fichier row_grid.xml en:
<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>
Veillez simplement à remplacer "path.to.item" par le package dans lequel réside votre classe GridViewItem.Java.
J'ai également supprimé votre parent LinearLayout car il ne faisait rien pour vous là-bas.
Éditer:
A également changé scaleType de fitXY à centerCrop afin que votre image ne s'étire pas et conserve son rapport d'aspect. Et, tant qu'il s'agit d'une image carrée, rien ne doit être rogné, malgré tout.
Vous pouvez remplacer votre disposition linéaire
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
}
}
puis utilisez-le dans le 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>
Fonctionne bien, merci! Une petite amélioration dont j'avais besoin serait toujours de choisir la valeur la plus petite, pour éviter un dépassement de l'écran:
@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);
}
}
import Android.content.Context;
import Android.util.AttributeSet;
import Android.widget.RelativeLayout;
public class GridViewItem extends RelativeLayout {
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
}
}
Si votre élément de grille a juste une image, alors le réponse est très bon. Mais si vous souhaitez ajouter plusieurs éléments dans votre vue de grille, vous devez créer votre GridViewItem personnalisé étendant la disposition que vous voulez que votre élément de grille soit. Par exemple, dans mon cas, j'avais RelativeLayout comme vue parent, j'ai donc créé GridViewItem étendant RelativeLayout et cela a fonctionné parfaitement.