GridView行重叠:如何使行高适合最高的项目?

2023-12-03

Like 前一个人,我在 GridView 项目之间有不需要的重叠:

GridView items overlapping

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

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

看着GridView 的源(不是权威副本,但 kernel.org 仍然处于关闭状态),我们可以在 fillDown() 和 makeRow() 中看到最后看到的 View 是“参考视图”:行的高度是根据该 View 的高度设置的,不是来自最高的那个。这解释了为什么最右边的列没问题。不幸的是,GridView 没有很好地设置让我通过继承来解决这个问题。所有相关字段和方法都是私有的。

所以,在我走上“克隆和拥有”这条老生常谈的臃肿道路之前,我在这里缺少什么技巧吗?我可以使用 TableLayout,但这需要我实现numColumns="auto_fit"我自己(因为我只想在手机屏幕上显示一长列),而且它也不会是 AdapterView,这感觉应该是这样。

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


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

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

/**
 * 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在视图单元格上设置所有适当的文本和图像。

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

最后,这是设置为在布局期间测量视图单元格的 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);
    }
}

我将列数作为资源的原因是这样我可以根据方向等拥有不同的数字。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GridView行重叠:如何使行高适合最高的项目? 的相关文章

随机推荐

  • 如何在Python中与beautifulsoup并行抓取多个html页面?

    我正在使用 Django Web 框架用 Python 制作一个 Web 抓取应用程序 我需要使用 beautifulsoup 库抓取多个查询 这是我编写的代码的快照 for url in websites r requests get u
  • 重写规则不适用于 IIS 上的 CakePHP

    我一直在尝试使用根文件夹中的以下 web config 设置来让重写规则在 IIS 上为 CakePHP 工作
  • 在 AlaSQL/JS-XLSX Excel 导出上定义单元格格式

    是否可以在 AlaSQL 导出到 Excel 时定义单元格格式 我正在维护一个使用 AlaSQL 将网格数据导出到 Excel 的系统 问题是 Excel 数据未转换为 NUMBER DATE 值可以 但数字类型始终显示为常规 通过在 JS
  • 如何在 Swift 中使用 UnsafeMutablePointer

    如何使用UnsafeMutablePointer
  • 带命名参数的 PDO 语句 VS 问号参数

    我有一个用于数据库管理的类 我的一个子类 定义查询的子类 是这样定义的 只是一个示例 实际上为了测试目的而删除了许多其他函数 namespace Tests SQL Arguments SQL query class Query publi
  • 批处理文件中 msg * 命令的高级用法?

    编辑 对于这个问题 我已经开始悬赏 50 美元给给出最佳答案的人 嗨 我想知道是否有一种方法可以使用批处理文件来使弹出窗口出现msg hi 命令以及除了默认情况下的选择 取消和确定 之外的其他选择 我的意思是向弹出消息添加自定义按钮 例如
  • 查找某个类元素的 Dom 节点索引

    您好 我有一系列不同类别的标签 单击跨度时 我想返回跨度类的索引 所以不是跨度本身的索引 这是一个示例 html span class spantype1 text1 span span class spantype2 text2 span
  • 如何找到SQL Server运行端口?

    是的 我读过这个如何找到 MS SQL Server 2008 的端口 no luck 远程登录1433 返回连接失败 所以我必须指定其他端口 我尝试使用 网络统计 abn 但我在这个列表中没有看到 sqlservr exe 或类似的东西
  • ExecuteReader CommandText 属性尚未正确初始化

    首先 如果某些代码不正确 我们深表歉意 我对在 vb net 上使用 sql 还很陌生 我有以下代码 Imports MySql Data MySqlClient Imports System Data SqlClient Public C
  • 引导加载程序如何读取 DVD(cd)?

    我有一个用汇编语言编写的第一阶段引导加载程序 我需要它从 DVD 或 CD 加载第二阶段引导加载程序 我只找到了从软盘或硬盘读取的示例 那里使用的中断是13h 在中断描述中它说它可以读取软盘和硬盘 我尝试使用 13h 来读取 CD 就好像它
  • SAS 宏 if then 条件将变量与数值进行比较

    我有一个包含多条路径的数据集 最后一个变量是人们遵循该路径的频率 data path input path1 path2 path3 path4 path5 path6 frequency cards 2 5 3 6 7 2 465 4 3
  • 在 woocommerce 购物车和结帐上显示重量和剩余重量消息

    我需要在 Wordpress 的购物车和结帐页面中向客户显示一条消息 此消息应显示购物车中产品的重量 并告诉他们剩余的重量需要支付相同的运费 以便他们可以花费相同的运费购买其他产品 有专门的插件吗 谢谢 以下代码将在购物车和结账页面中显示自
  • sqlite中的外键定义

    无法在 sqlite 中添加外键约束 从 SQLite 3 6 19 开始 SQLite 支持外键 您需要通过以下方式启用它们 sqlite gt PRAGMAforeign keys ON 为了向后兼容 它们默认处于关闭状态 See th
  • 设置 JTable 中列的数据类型

    我创建了一个带有表模型的 JTable 现在 根据我所拥有的输入 我想将一列设置为特定的数据类型 我该怎么做呢 import java awt GridLayout import javax swing import javax swing
  • PHP - “print/echo”显示结束标签 - 或不输出

    启动一些 PHP 并对 echo print 的工作方式感到困惑 我的代码中有这个代码index html 我的页面上的输出是 Hello World gt 如果我删除 div 标签 我没有得到任何输出 使用echo产生相同的行为 这是怎么
  • 如何将网页不可用页面替换为自定义页面? (网页浏览)

    我想更改页面Webpage not Available or ERR NAME NOT RESOLVED to 我的页面 没有互联网连接 如果再次在线或连接互联网 则可以使用刷新按钮返回在线状态 如果未连接 则留在页面中没有网络连接 看起来
  • 如何循环遍历特定表单的所有打开实例?

    我需要更新动态创建的 Form2 的列表框 假设我必须更新此 ListBox 当然在 Form1 中 我没有此 Form2 的引用 因此我无法调用 UpdateList 方法 不 我不能将其设为静态 我什至不知道有没有打开Form2 可能有
  • 将元素插入数组C

    我有一个之前已经排序过的数字数组 所以不需要对其进行排序 我需要插入一个给定的值 将其命名val 位于我的数组中的有效位置 我的程序适用于小于上一个值的给定值 但对于该值大于上一个值的情况 我的程序只是不想插入该值 例如 对于数组 1 2
  • Oracle 动态 sql 与触发器使用:新和:旧变量

    我正在尝试使用 all tab columns 将大型触发器代码简化为简洁的代码 因为表包含 200 列 由于某种原因 当尝试使用动态 sql 时 它不允许我更新声明的变量 DECLARE v new rec SOME TABLE ROWT
  • GridView行重叠:如何使行高适合最高的项目?

    Like 前一个人 我在 GridView 项目之间有不需要的重叠 注意除了最右边的一列之外的每一列中的文本 我与上一个问题的不同之处在于我不想要恒定的行高 我希望行高变化为容纳最高的内容在每一行中 以有效利用屏幕空间 看着GridView