如何强制 GridView 在 Android 中生成方形单元格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24416847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:06:05  来源:igfitidea点击:

How to force GridView to generate square cells in Android

androidgridviewlayout

提问by Jessica

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 !

如何强制 android GridView 生成方形单元格(单元格的高度等于单元格的宽度) GridView 有 10*9 个单元格并且应用程序必须支持多个屏幕!

I used a Linear Layout:

我使用了线性布局:

row_grid.xml

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

和 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

GridView 的每个单元格都包含一个具有相同宽度和高度的图像。图像比单元格大,必须拉伸以适应单元格。 在此处输入图片说明

回答by Cruceo

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:

首先,您将要创建一个自定义 View 类,您可以使用它来代替您正在使用的默认 LinearLayout。然后你想覆盖视图的 onMeasure 调用,并强制它是方形的:

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:

然后您可以将 row_grid.xml 文件更改为:

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

只需确保将“path.to.item”更改为 GridViewItem.java 类所在的包。

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

我还删除了您的 LinearLayout 父项,因为它在那里没有为您做任何事情。

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.

还将 scaleType 从 fitXY 更改为 centerCrop 以便您的图像不会自行拉伸并保持其纵横比。而且,只要它是方形图像,无论如何都不应裁剪任何内容。

回答by Hossam Alaa

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

然后在 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>

回答by u635504

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

}

回答by Jain

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

如果您的网格项目只有一个图像,那么答案非常好。但是你想在你的网格视图中添加多个项目,那么你必须创建你的自定义 GridViewItem 扩展你想要你的网格项目的布局。例如,在我的例子中,我将 RelativeLayout 作为父视图,所以我创建了 GridViewItem 扩展了 RelativeLayout 并且它完美地工作。

回答by Abhishek Shukla

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

只要确保您的图像是方形的。并使容器 wrap_content。