概括: 尝试通过自定义适配器包装器动态地将标题行添加到ListView。 ListView在保持滚动位置的同步方面遇到困难。提供了可运行的演示项目。

我想根据Cursoradapter中的值动态地将项目添加到列表中,这是用户当前查看的几个位置。为此,我有一个适配器,可以包裹Cursoradapter,并将新内容保留在Sparsearray中。当物品添加到自定义适配器中时,需要更新listView,但是我遇到了很多陷阱,试图使其工作并希望一些建议。

演示项目可以在此处下载: dynamicsectionedlist.zip

在演示中,通过寻找10个位置以找到列表项切换到下一个字母的正确位置,通过查找正确的位置来动态添加标题。 NotifyDataSthanged的每个实施都有所述问题:

演示1该演示显示了NotifyDataSetchanged()的重要性。单击任何内容时,该应用将崩溃。这是由于ListView中的一些理智检查... mItemCount != adapter.getItemCount(). 。道德是,我们需要通知列表,数据已更改。

演示2自然的下一步是在发生更改时通知更改的列表视图。不幸的是,在ListView滚动时,这样做会牢固地打破所有触摸交互,直到应用程序切换到触摸模式为止。您需要“滚动滚动”足够远,以生成新的标题才能注意到这一点。点击屏幕不会导致滚动停止,一旦停止,列表项目都不会单击。这是由于一些 if (!mDataChanged) { /* do very important stuff */ } abslistview.ontouchevent()中的代码。

演示3为了解决此问题,Demo 3引入了pendingChanges标志,并且自定义适配器获得了notifyDataSetchangedifneed(),一旦它输入了“安全”状态以进行更改。必须在listView.layoutchildren()中通知更改的第一个点,因此我将该方法覆盖以在需要时首先通知更改,然后致电。越过至少一个标题,然后单击列表项。

尽管我不确定为什么,但这并不完全正确。用键盘/轨迹球敲击或选择项目会导致列表刷新,而无需正确同步旧位置。它滚动到列表的顶部,这是不可接受的。

演示4演示3中的滚动问题至少可以在触摸模式下征服。通过在触摸时添加一个通话来通知DataSetchangedifneedeed(),数据更改发生在所有触摸交互作用时都可以按预期工作和列表位置正确同步的时间进行。

但是,当设备不处于触摸模式时,我找不到一个模拟,更不用说它绝对像是黑客了。列表几乎总是滚动回到顶部,我找不到是什么原因导致它偶尔保持正确的位置。

由于Android在每一步都在与我战斗,因此我觉得应该有更好的方法。请尝试演示,如果可以应用任何修复程序以使其正常工作!

非常感谢任何能够调查的人,希望如果我们能够获得代码,这对于其他试图实现标题列表相同优化的人将很有用。

有帮助吗?

解决方案

上面介绍的方法的主要问题是,数据集直接从超级类执行的代码内部更改。通过在GetView()中填充标题,我正在更改数据中的中间或超类中的“不安全”状态。这就是为什么在滚动卷轴期间打电话给notifyDataSthanged时,所有触摸互动都会破裂的原因。数据需要从外部来源添加,而不是从适配器方法中添加。

可以通过使用处理程序或异步函数将标题添加到适配器并调用其notifyDataSthanged来完成。这些将在UI线程上运行,不会干扰超类状态。得益于Commonsware的EndlessSAdapter示例,介绍了asynctask的概念以将数据添加到列表中。

进行更改后不再需要OnTouchEvent()和LayoutChildren()hacks。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top