使GridView项目成为正方形

ana*_*gaf 77 android gridview

我希望我的项目GridView是正方形的.有2列,项目宽度为fill_parent(例如,它们占用尽可能多的水平空间.这些项目是自定义视图.

如何使项目高度等于其可变宽度?

jda*_*mcd 107

当GridView列被拉伸时,有一个更简单的解决方案.只需覆盖GridView项目布局的onMeasure ...

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
Run Code Online (Sandbox Code Playgroud)

  • 大约1:这就是它的正方形 - " (11认同)
  • 一个完整的答案会很好.你是说扩展gridview吗? (3认同)
  • @KarthikPalanivelu这将用于网格项的布局,而不是GridView本身.您可以使用此代码段将RelativeLayout扩展到SquareRelativeLayout. (2认同)

Chr*_*ins 54

或者,如果您想扩展View,只需执行一些非常简单的操作:

public class SquareImageView extends ImageView
{

    public SquareImageView(final Context context)
    {
        super(context);
    }

    public SquareImageView(final Context context, final AttributeSet attrs)
    {
        super(context, attrs);
    }

    public SquareImageView(final Context context, final AttributeSet attrs, final int defStyle)
    {
        super(context, attrs, defStyle);
    }


    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
    {
        final int width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        setMeasuredDimension(width, width);
    }

    @Override
    protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh)
    {
        super.onSizeChanged(w, w, oldw, oldh);
    }
}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,这super.onMeasure()不是必需的.onMeasured要求是你必须打电话setMeasuredDimension.

  • 像魅力的工作..谢谢克里斯:) (2认同)
  • @Chris.Jenkins我不同意你的上一条评论:如果我不调用`super.onMeasure()`,则不会绘制放置在其中的ImageView.因此它似乎需要作为`onMeasure`方法的第一行. (2认同)

Gre*_*ory 15

我不确定当前的小部件是否可行.您最好的选择可能是将自定义视图放在自定义"SquareView"中.此视图可以只包含1个子视图,并在调用onLayout方法时强制高度等于宽度.

我从来没有尝试过这样的事情,但我认为这不应该太难.另一种(也许稍微更容易)解决方案可能是将自定义视图的根布局子类化(例如,如果它是LinearLayout,则生成SquareLinearLayout),并将其用作容器.

编辑:这是一个基本的实现,似乎对我有用:

package com.mantano.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class SquareView extends ViewGroup {

    public SquareView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int u, int r, int d) {
        getChildAt(0).layout(0, 0, r-l, d-u); // Layout with max size
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        View child = getChildAt(0);
        child.measure(widthMeasureSpec, widthMeasureSpec);
        int width = resolveSize(child.getMeasuredWidth(), widthMeasureSpec);
        child.measure(width, width); // 2nd pass with the correct size
        setMeasuredDimension(width, width);
    }
}
Run Code Online (Sandbox Code Playgroud)

它的设计是为了拥有一个独特的孩子,但为了简单起见,我忽略了所有的检查.基本思想是使用GridView设置的宽度/高度参数测量子节点(在我的例子中,它使用numColumns = 4来计算宽度),然后使用最终尺寸进行第二次传递,其中height = width. ..布局只是一个简单的布局,它将唯一的子项布局在(0,0)所需的尺寸(左右,向下).

这是用于GridView项目的XML:

<?xml version="1.0" encoding="utf-8"?>
<com.mantano.widget.SquareView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="wrap_content">

    <LinearLayout android:id="@+id/item" android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:orientation="horizontal"
        android:gravity="center">

        <TextView android:id="@+id/text" android:layout_width="fill_parent"
            android:layout_height="wrap_content" android:text="Hello world" />
    </LinearLayout>
</com.mantano.widget.SquareView>
Run Code Online (Sandbox Code Playgroud)

我在SquareView中使用了LinearLayout,以便管理所有重力可能性,边距等.

我不确定这个小部件对方向和尺寸变化的反应有多好(或不好),但它似乎正常工作.


Ste*_*man 12

它最终很容易让网格项目正方形.

在网格适配器的"GetView"方法中,只需执行以下操作:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    GridView grid = (GridView)parent;
    int size = grid.getRequestedColumnWidth();

    TextView text = new TextView(getContext());
    text.setLayoutParams(new GridView.LayoutParams(size, size));

    // Whatever else you need to set on your view

    return text;
}
Run Code Online (Sandbox Code Playgroud)

  • 不得不用"getColumnWidth"替换"getRequestedColumnWidth",它对我有用..谢谢! (3认同)

Luc*_*ese 6

我不知道这是不是最好的方法,但是我完成了那个使我的自定义视图以这种方式覆盖onSizeChanged:

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);

    if (getLayoutParams() != null && w != h) {
        getLayoutParams().height = w;
        setLayoutParams(getLayoutParams());
    }
}
Run Code Online (Sandbox Code Playgroud)

我在LinearLayout和GridView中使用这个自定义视图,它们都显示正方形!


Ann*_*ire 6

这对我有用!

如果你像我一样,你不能使用getRequestedColumnWidth(),因为你的minSdk低于16,我建议这个选项.

  1. 在你的片段中:

    DisplayMetrics dm = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); int size = dm.widthPixels / nbColumns; CustomAdapter adapter = new CustomAdapter(list, size, getActivity());

  2. 在您的适配器中(在getView(int position,View convertView,ViewGroup parent))

    v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));

  3. fragment.xml之:

    <GridView android:id="@+id/gridView" android:layout_width="match_parent" android:layout_height="match_parent" android:horizontalSpacing="3dp" android:verticalSpacing="3dp" android:numColumns="4" android:stretchMode="columnWidth" />

  4. custom_item.xml :(例如)

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/picture" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" />

希望它会帮助别人!


Mar*_*nci 5

如果在xml中设置静态列数,则可以获取视图的宽度并将其除以列数.

如果你正在使用auto_fit那么获取列数会有点棘手(没有getColumnCount()方法),顺便说一句这个问题应该以某种方式帮助你.

这是我getView(...)用于具有固定列数的适配器方法的代码:

    item_side = mFragment.holder.grid.getWidth() / N_COL;
    v.getLayoutParams().height = item_side;
    v.getLayoutParams().width = item_side;
Run Code Online (Sandbox Code Playgroud)


Art*_*Art 5

尝试

<GridView
...
android:stretchMode="columnWidth" />
Run Code Online (Sandbox Code Playgroud)

您也可以使用其他模式