我正在设计一款Android游戏,我试图使用ListView。该列表使用BaseAdapter,并填充ArrayList。当用户按下确定按钮时,我滚动到列表顶部,然后遍历列表中的每个士兵。我设置了士兵的一个子视图的背景drawable,这样它就是一个显示" hit"或"想念"。我使用了一个Handler.postDelayed(),以便每个动画都可以在它之前完成。
问题是我无法修改不可见的视图。我的列表中一次最多可包含13名士兵,但最多只能显示5名士兵。所以一旦我击中了第六名士兵,我就会因使用ListView.getChildAt(soldierArrayIndex)而得到一个空指针异常。我的解决方案是在getChildAt()调用之前添加smoothScrollTo(soldierArrayIndex)以使其可见,但问题仍然存在。
所以我的问题并非如此"如何修复我的代码?"。我更想知道是否有办法禁用ListView的回收。我使用getChildAt()的原因是因为我需要在它返回的视图上使用findViewById(),然后修改ID找到的视图。但是,如果视图从未被回收,则getChildAt()将不会返回null。
我的另一个想法是只使用滚动视图,输入我创建的13个士兵视图实例,然后设置我目前没有使用的那些"去掉#34;。我唯一的问题是我不知道如何迭代这些观点。
TL; DR:如何更新列表视图中当前不可见的视图(它们目前是"已回收")?
答案 0 :(得分:1)
我认为你在这里混淆了模特和视图。
适配器视图采用通常可以访问整个数据集的适配器。因此,即使您的ListView只渲染屏幕上可见的项目,您仍然可以通过调用适配器上的getItem(位置)来访问屏幕外项目。
您似乎直接在适配器上调用getView。
我建议您不要这样做,因为这不是AdapterViews和Adapters的设计方式。相反,当模型中的某些内容发生更改时(通过notifyDataSetChanged),您需要向ListView指示并将其留给ListView以代表您调用适配器的getView方法。
我想事件的顺序是这样的:
对于“offscreen”士兵(在ListView的滚动区域中看不到的士兵),ListView不需要渲染它们,因此它不会在这些位置上调用getView。
但是,如果屏幕外的士兵现在滚动到视图中,ListView将使用该阵列中士兵的位置调用适配器的getView方法。
最后,如果您希望更精细地控制AdapterView如何更新自身,您可以考虑使用RecyclerView,因为它允许您逐项通知更改。