使GridView项目正方形

我想我的GridView的项目是方形的。 有2列,项目宽度是fill_parent (例如,他们尽可能多的水平空间,这些项目是自定义视图。

我如何使项目高度等于他们的可变宽度?

当GridView列被拉伸时,有一个更简单的解决scheme。 只需重写GridView项目布局的onMeasure …

 @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } 

或者,如果你想扩展一个视图只需要做一些非常简单的事情:

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

值得注意的是, super.onMeasure()是不需要的。 onMeasured需求是你必须调用setMeasuredDimension

我不确定这是可以与当前的小部件。 你最好的select可能是将自定义视图放在一个自定义的“SquareView”中。 这个视图可以包含1个子视图,并且在调用onLayout方法时强制高度等于宽度。

我从来没有尝试过这样做,但我认为这不应该太困难。 另一种解决scheme(也许稍微简单一点)可能是将自定义视图的根布局(例如,如果是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, rl, du); // 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); } } 

它被devise成有一个独特的孩子,但为了简单起见,我忽略了所有的检查。 基本的想法是用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> 

我在SquareView中使用了一个LinearLayout,以便pipe理所有的重力可能性,边距等。

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

它最终是相当容易得到网格项目广场。

在你的网格适配器的“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; } 

我不知道这是否是最好的方法,但我完成了使我的自定义视图重写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()); } } 

我在LinearLayout和GridView里面使用这个自定义视图,并且都显示正方形!

这对我有用!

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

  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位置,查看convertView,ViewGroup父))

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

希望它会帮助别人!

如果您在xml中设置了一个静态数量的列,那么您可以将视图的宽度除以列数。

如果你正在使用auto_fit那么获得列计数将会有点棘手(没有getColumnCount()方法),顺便说一句, 这个问题应该可以帮助你。

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

  item_side = mFragment.holder.grid.getWidth() / N_COL; v.getLayoutParams().height = item_side; v.getLayoutParams().width = item_side; 

这就是我正在做的GridView中显示正方形单元格。 我不确定你是否想要方格或别的东西。

 GridView grid = new GridView( this ); grid.setColumnWidth( UIScheme.cellSize ); grid.setVerticalSpacing( UIScheme.gap ); grid.setStretchMode( GridView.STRETCH_COLUMN_WIDTH ); grid.setNumColumns( GridView.AUTO_FIT ); 

然后,我为每个单元格创build的视图,我必须做到以下几点:

 cell.setLayoutParams( new GridView.LayoutParams(iconSize, iconSize) ); 

尝试

 <GridView ... android:stretchMode="columnWidth" /> 

你也可以玩其他模式

基于SteveBorkman的答案 ,即API 16+:

 @Override public View getView(int position, View convertView, ViewGroup parent) { GridView grid = (GridView)parent; int size = grid.getColumnWidth(); if (convertView == null){ convertView = LayoutInflater.from(context).inflate(R.layout.your_item, null); convertView.setLayoutParams(new GridView.LayoutParams(size, size)); } //Modify your convertView here return convertView; } 

沿着@格雷戈里的答案,我不得不将我的图像包裹在一个LinearLayout中,以防止GridView从正方形操纵其尺寸。 请注意,应该将外部的LinearLayout设置为具有图像的尺寸,并且GridView列的宽度应该是图像的宽度和任何边距。 例如:

  <!-- LinearLayout wrapper necessary to wrap image button in order to keep square; otherwise, the grid view distorts it into rectangle. also, margin top and right allows the indicator overlay to extend top and right. NB: grid width is set in filter_icon_page.xml, and must correspond to size + margin --> <LinearLayout android:id="@+id/sport_icon_lay" android:layout_width="60dp" android:layout_height="60dp" android:orientation="vertical" android:layout_marginRight="6dp" android:layout_marginTop="6dp" > <ImageButton android:id="@+id/sport_icon" android:layout_width="60dp" android:layout_height="60dp" android:maxHeight="60dp" android:maxWidth="60dp" android:scaleType="fitCenter" /> </LinearLayout> 

和GridView一样:

  <GridView android:id="@+id/grid" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true" android:columnWidth="66dp" android:numColumns="auto_fit" android:verticalSpacing="25dp" android:horizontalSpacing="24dp" android:stretchMode="spacingWidth" /> 

在你的活动中

  DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); valX = displaymetrics.widthPixels/columns_number; 

在GridView的CustomAdapter中

  v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, YourActivity.valX));