How to force GridView to generate square cells in

2020-02-16 12:25发布

How can I force an android GridView to generate square cells (Cell's height equal to cell's width) GridView has 10*9 cells and the app must support multiple screens !

I used a Linear Layout:

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>

and 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>

Each cell of GridView contains a image that has same width and height. images are larger than cells and must stretch to fit in cells. enter image description here

5条回答
对你真心纯属浪费
2楼-- · 2020-02-16 12:55

Works nicely, thank you! A small improvement I required would be always pick the smaller value, to prevent overshooting the screen:

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

}
查看更多
Evening l夕情丶
3楼-- · 2020-02-16 12:57

You can Override your linear layout

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

then use it in the 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>
查看更多
乱世女痞
4楼-- · 2020-02-16 12:58

First, you're going to want to create a custom View class that you can use instead of the default LinearLayout you're using. Then you want to override the View's onMeasure call, and force it to be square:

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

Then you can change your row_grid.xml file to:

<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>

Just be sure to change "path.to.item" to the package where your GridViewItem.java class resides.

I also removed your LinearLayout parent since it wasn't doing anything for you there.

Edit:

Also changed scaleType from fitXY to centerCrop so that your image doesn't stretch itself and maintains its aspect ratio. And, as long as it's a square image, nothing should be cropped, regardless.

查看更多
何必那么认真
5楼-- · 2020-02-16 13:00
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
    }
}

If your grid item just have an image then the answer is very good. But you want to add multiple items in your grid view then you must create Your Custom GridViewItem extending the layout you want your grid item to be. For example in my case I had RelativeLayout as the parent view so I created GridViewItem extending the RelativeLayout and it worked flawlessly.

查看更多
ゆ 、 Hurt°
6楼-- · 2020-02-16 13:16

Just make sure that your images are square. And make the container wrap_content.

查看更多
登录 后发表回答