web-dev-qa-db-fra.com

Comment forcer GridView à générer des cellules carrées dans Android

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. enter image description here

24
Jessica

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.

83
Cruceo

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>
12
Hossam Alaa

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);
    }

}
3
最白目
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.

0
Jain