我希望我的GridView
的项是正方形的。该视图有两列,项的宽度为fill_parent
(即它们尽可能占用水平空间)。这些项是自定义视图。
如何使这些项的高度等于它们可变的宽度?
当GridView的列被拉伸时,有一个更简单的解决方案。只需重写GridView项布局的onMeasure方法即可...
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
或者,如果您想扩展一个视图(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);
}
}
super.onMeasure()
。 onMeasured
的要求是必须调用 setMeasuredDimension
。super.onMeasure()
,那么放置在其中的ImageView将不会被绘制。因此,它似乎是onMeasure
方法的必要第一行。 - cyrilchampierpackage 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);
}
}
为了简单起见,我忽略了所有检查,但它被设计为只有一个独特的子元素。基本思路是使用GridView设置的宽度/高度参数来测量子元素(在我的情况下,它使用numColumns = 4来计算宽度),然后进行第二次遍历并使用最终尺寸,其中高度=宽度...
布局只是一个简单的布局,将独特的子元素布局在(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,以便让它管理所有的重力可能性、边距等。
我不确定这个小部件在方向和尺寸变化方面的反应如何,但它似乎能够正确地工作。
最终得到网格项正方形的方法实际上非常简单。
在您的网格适配器的“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;
}
getColumnWidth
替换getRequestedColumnWidth
,这对我起作用了...谢谢! - Yahyanew GridView.LayoutParams(size, size);
替换为 new GridView.LayoutParams(new ViewGroup.LayoutParams(size, size));
。 - Prajjwal Srivastav我不知道这是否是最好的方法,但是我通过制作自定义视图来实现覆盖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中使用这个自定义视图,在两者中都显示为正方形!
请尝试
<GridView
...
android:stretchMode="columnWidth" />
这对我很有效!
如果像我一样,由于您的minSdk低于16而无法使用getRequestedColumnWidth(),我建议使用以下选项。
在您的fragment中:
DisplayMetrics dm = new DisplayMetrics();
getActivity()。getWindowManager()。getDefaultDisplay()。getMetrics(dm);
int size = dm.widthPixels / nbColumns;
CustomAdapter adapter = new CustomAdapter(list, size, getActivity());
在您的adapter中(在getView(int position,View convertView,ViewGroup parent)中):
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" />
希望对某些人有所帮助!
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 );
我需要为每个单元格创建的视图做以下操作:
cell.setLayoutParams( new GridView.LayoutParams(iconSize, iconSize) );
根据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;
}