使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议这个选项。
-
在你的片段中:
DisplayMetrics dm = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); int size = dm.widthPixels / nbColumns; CustomAdapter adapter = new CustomAdapter(list, size, getActivity());
-
在你的适配器(在getView(int位置,查看convertView,ViewGroup父))
v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, size));
-
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" />
-
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));