gpt4 book ai didi

安卓 ListView : Updating invisible views or disabling recycling

转载 作者:行者123 更新时间:2023-11-30 01:46:34 24 4
gpt4 key购买 nike

我正在设计一个 Android 游戏,我正在尝试使用 ListView。该列表使用一个 BaseAdapter,并填充了一个 ArrayList。当用户按下 ok 按钮时,我滚动到列表的顶部,然后遍历列表中的每个士兵。我设置了士兵的其中一个 subview 的可绘制背景,以便它是一个显示“命中”或“未命中”的短动画。我使用了 Handler.postDelayed() 以便每个动画完成之前的动画。

问题是我无法修改不可见的 View 。我的列表中一次最多有 13 个士兵,但最多只能显示 5 个。因此,一旦我击中了第六个士兵,我就会从使用 ListView.getChildAt(soldierArrayIndex) 中得到一个空指针异常。我的解决方案是在 getChildAt() 调用之前添加 smoothScrollTo(soldierArrayIndex) 以使其可见,但问题仍然存在。

所以我的问题不完全是“如何修复我的代码?”。我更想知道是否有办法禁用 ListView 所做的回收。我使用 getChildAt() 的原因是因为我需要在它返回的 View 上使用 findViewById(),然后修改通过 ID 找到的 View 。但是,如果 View 从未被回收,则 getChildAt() 不会返回 null。

我的另一个想法是只使用 ScrollView ,输入我创建的 Soldier View 的 13 个实例,然后将我当前不使用的那些设置为“消失”。我唯一的问题是我不知道如何遍历这些 View 。

TL;DR:如何更新当前在 ListView 中不可见的 View (它们当前是“回收的”)?

最佳答案

我认为您在这里混淆了模型和 View 。

适配器 View 采用通常可以访问整个数据集的适配器。因此,即使您的 ListView 只会呈现屏幕上可见的项目,您仍然应该能够通过在适配器上调用 getItem(position) 来访问您的屏幕外项目。

您似乎是直接在适配器上调用 getView。

我建议您不要这样做,因为这不是 AdapterView 和适配器的设计方式。相反,当模型中的某些内容发生更改(通过 notifyDataSetChanged)时,您需要向 ListView 发出指示,并将其留给 ListView 代表您调用适配器的 getView 方法。

我想象事件的顺序是这样的:

  1. 更新士兵对象
  2. 在您的适配器上调用 notifyDataSetChanged,它会告诉您的 ListView 它需要重绘内容
  3. ListView 遍历可见的 Soldier 项目,对每个项目调用 getView(int position, View convertView, ViewGroup parent)。
  4. 适配器中的 getView 实现获取指定位置的 Soldier,并确定 View 在该时间点的外观。

对于“屏幕外”士兵(那些在 ListView 的滚动区域中不可见的士兵),ListView 不需要渲染它们,因此它不会在这些位置调用 getView。

但是,如果屏幕外的 Soldier 现在滚动到 View 中,ListView 将使用该 Soldier 在数组中的位置调用适配器的 getView 方法。

最后,如果您想要更细粒度地控制 AdapterView 应如何 self 更新,您可以考虑 RecyclerView,因为它允许您逐项通知更改。

关于安卓 ListView : Updating invisible views or disabling recycling,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33632892/

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