gpt4 book ai didi

android - GridView 行重叠 : how to make row height fit the tallest item?

转载 作者:IT王子 更新时间:2023-10-28 23:55:05 24 4
gpt4 key购买 nike

喜欢 this previous person ,我在 GridView 项目之间有不必要的重叠:

GridView items overlapping

注意除最右边之外的每一列中的文本。

我与上一个问题的不同之处在于我不想要恒定的行高。我希望行高变化以容纳每行中最高的内容,以有效利用屏幕空间。

source for GridView (不是权威副本,但是 kernel.org 还是挂了),我们可以在 fillDown() 和 makeRow() 中看到最后看到的 View 是“引用 View ”:行的高度是从那个 View 的高度设置的,不是从最高的那个。 这解释了为什么最右边的列没问题。不幸的是,GridView 没有很好地设置,我无法通过继承来解决这个问题。所有相关的字段和方法都是私有(private)的。

所以,在我采取“克隆并拥有”这种陈旧臃肿的道路之前,这里有没有我遗漏的技巧?我可以使用 TableLayout,但这需要我实现numColumns="auto_fit"我自己(因为我想要例如手机屏幕上的一长列),而且它也不会是 AdapterView,这感觉应该是。

编辑:实际上,克隆和拥有在这里并不实用。 GridView 依赖于其父类和兄弟类的不可访问部分,并且会导致导入至少 6000 行代码(AbsListView、AdapterView 等)

最佳答案

我使用静态数组来驱动行的最大高度。这并不完美,因为在重新显示单元格之前不会调整早期列的大小。这是膨胀的可重用内容 View 的代码。

编辑:我正确地完成了这项工作,但我在渲染之前预先测量了所有单元格。我通过继承 GridView 并在 onLayout 方法中添加测量 Hook 来做到这一点。

/**
* Custom view group that shares a common max height
* @author Chase Colburn
*/
public class GridViewItemLayout extends LinearLayout {

// Array of max cell heights for each row
private static int[] mMaxRowHeight;

// The number of columns in the grid view
private static int mNumColumns;

// The position of the view cell
private int mPosition;

// Public constructor
public GridViewItemLayout(Context context) {
super(context);
}

// Public constructor
public GridViewItemLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}

/**
* Set the position of the view cell
* @param position
*/
public void setPosition(int position) {
mPosition = position;
}

/**
* Set the number of columns and item count in order to accurately store the
* max height for each row. This must be called whenever there is a change to the layout
* or content data.
*
* @param numColumns
* @param itemCount
*/
public static void initItemLayout(int numColumns, int itemCount) {
mNumColumns = numColumns;
mMaxRowHeight = new int[itemCount];
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Do not calculate max height if column count is only one
if(mNumColumns <= 1 || mMaxRowHeight == null) {
return;
}

// Get the current view cell index for the grid row
int rowIndex = mPosition / mNumColumns;
// Get the measured height for this layout
int measuredHeight = getMeasuredHeight();
// If the current height is larger than previous measurements, update the array
if(measuredHeight > mMaxRowHeight[rowIndex]) {
mMaxRowHeight[rowIndex] = measuredHeight;
}
// Update the dimensions of the layout to reflect the max height
setMeasuredDimension(getMeasuredWidth(), mMaxRowHeight[rowIndex]);
}
}

这是我的 BaseAdapter 子类中的测量函数。请注意,我有一个方法 updateItemDisplay 可以在 View 单元格上设置所有适当的文本和图像。

    /**
* Run a pass through each item and force a measure to determine the max height for each row
*/
public void measureItems(int columnWidth) {
// Obtain system inflater
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate temp layout object for measuring
GridViewItemLayout itemView = (GridViewItemLayout)inflater.inflate(R.layout.list_confirm_item, null);

// Create measuring specs
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(columnWidth, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

// Loop through each data object
for(int index = 0; index < mItems.size(); index++) {
String[] item = mItems.get(index);

// Set position and data
itemView.setPosition(index);
itemView.updateItemDisplay(item, mLanguage);

// Force measuring
itemView.requestLayout();
itemView.measure(widthMeasureSpec, heightMeasureSpec);
}
}

最后,这里是设置为在布局期间测量 View 单元格的 GridView 子类:

/**
* Custom subclass of grid view to measure all view cells
* in order to determine the max height of the row
*
* @author Chase Colburn
*/
public class AutoMeasureGridView extends GridView {

public AutoMeasureGridView(Context context) {
super(context);
}

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

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

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(changed) {
CustomAdapter adapter = (CustomAdapter)getAdapter();

int numColumns = getContext().getResources().getInteger(R.integer.list_num_columns);
GridViewItemLayout.initItemLayout(numColumns, adapter.getCount());

if(numColumns > 1) {
int columnWidth = getMeasuredWidth() / numColumns;
adapter.measureItems(columnWidth);
}
}
super.onLayout(changed, l, t, r, b);
}
}

我将列数作为资源的原因是我可以根据方向等设置不同的列数。

关于android - GridView 行重叠 : how to make row height fit the tallest item?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7545915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com