请教一下, Android 里的 ListView 如何实时更新数据并逐条显示?

2020-11-30 12:58:36 +08:00
 ww050312
想做类似微信对话那种形式的 listview,但是是后台接受到十几个数据后依次添加到 arraylist 里,每次 arraylist.add(item)之后就调用 notifyDataSetChanged()方法想让视图上出现新的一行,3s 之后再添加第二行,可是用 for loop 之后发现就算我在每次 notifyDataSetChanged 之后延迟 3s 也会变成 3s 之后所有数据一次性出现在视图上……已经彻底懵了。请问一下有什么可行的方式实现吗?
2139 次点击
所在节点    问与答
32 条回复
ww050312
2020-11-30 13:10:43 +08:00
upup
ww050312
2020-11-30 13:10:53 +08:00
upupup
SelectLanguage
2020-11-30 13:24:08 +08:00
有刷新单条数据的方法
kop1989
2020-11-30 13:30:42 +08:00
意思是,不管真实的数据来多少条。ListView 你也想每隔 3 秒冒出一条来?

那就需要你用一个单独的线程去每隔三秒添加一条记录给你 adapter 绑定的数据源。
然后调用你说的 notifyDataSetChanged();
ww050312
2020-11-30 13:31:34 +08:00
@SelectLanguage 这个我会,或者用按钮单击逐条添加数据也会,就是不知道怎么自动化逐条添加 orz 包括 debug 的时候它也是一直黑屏,直到整个 for loop 执行完毕后才能出现完整视图 同时 list view 也就一次性显示了所有数据……
kop1989
2020-11-30 13:42:19 +08:00
换句话说,就是不要把你接收消息的 List ( A )当作 adapter 的数据源。
要单独 new 一个 List ( B )作为 adapter 的数据源,然后每隔三秒,从 A 取一条加入 B 。

当然,还有其他做法(不建议这么做),比如自定义 Adapter,然后重写 setView (名字不确定)方法,在 setView 方法里处理应该显示的 item 数量。然后外侧每隔三秒 notifyAll();
ww050312
2020-11-30 13:42:43 +08:00
@kop1989 orz 对的 可以请教一下更详细的操作吗,刚刚查了一下安卓插入线程的方式看得很晕,是要用 Handler 吗?
kop1989
2020-11-30 13:45:35 +08:00
@ww050312 #7 可以搜索关键词《 java 定时器》来解决你的问题。(当然,前提你是用的 java 来开发 android,用其他语言就搜其他语言的定时器)
evitceted
2020-11-30 13:45:48 +08:00
实在不懂需求
ww050312
2020-11-30 13:56:23 +08:00
@evitceted 就类似微信不断从顶端弹出消息那种(?
zeropercenthappy
2020-11-30 13:58:59 +08:00
按楼上说的,数据源不要直接使用,给你的 adapter 重新 new 一个集合当作数据源,每 3s 从原始数据源里取一条数据。
Android 里有一个很方便的倒计时类 CountDownTimer,你实在不会的话可以考虑用它。
。总时长可以用 Long.MAX_VALUE,步长按你的需要设置为 3000ms 。
在 onTick 回调里取数据就行了,不需要你关心子线程主线程的事。
kop1989
2020-11-30 13:59:54 +08:00
@evitceted #9 这种在包装 app 热度的时候很常见。比如一些社交类 app,没准机器人给你发的信息就是直接一个接口取下来的。但是你展示的时候肯定要一会冒出来一个。否则就太假了。
ww050312
2020-11-30 14:01:26 +08:00
@kop1989 所以大概过程就是在定时器里放一个任务,同时在定时器激活前要 new 一个 list (全局变量吗?)然后在定时器内:不断将数据加到新的 arraylist 里面,同时 notifyDataSetChanged()。
我对 NotifyDataSetChanged 这个函数的功能很懵,看源代码像是同步但是搜出来又很多说它异步。
非常感谢!!
ww050312
2020-11-30 14:02:53 +08:00
@zeropercenthappy !好的,立刻去尝试一下。
Porster
2020-11-30 14:04:30 +08:00
你需要准备 2 个 list,一个是网络数据 ListA 。一个是在适配器里的数据 ListB 。
每次操作只往适配器里的 ListB 增加 1 条,再调用 notifyDataSetChanged 。
如此循环 listA.size 次后,你的 ListView 才完全展示完毕
ww050312
2020-11-30 14:04:52 +08:00
@kop1989 对对,我其实就是想要这种连续的自动回复的效果……我表述能力太差了 = =
ww050312
2020-11-30 14:06:33 +08:00
@Porster 我现在就是这么操作的,但是它会在最后直接全部显示……特别迷惑的是即便我中间调用了延时,也必然是最后全部结束后才一起画出来= =
kop1989
2020-11-30 14:08:11 +08:00
@ww050312 #13 你可以近似理解为就是一个“观察者模式”的实际范例(这么说其实不严谨),大概逻辑就是他会根据数据源的数据变化“局部刷新”ListView 的 Layout 。
具体的就不赘述了,可以自己搜索一下,应该对你对于“设计模式”的理解有帮助。
zeropercenthappy
2020-11-30 14:14:11 +08:00
@kop1989 你扯远了

根据 #5 的回复 “包括 debug 的时候它也是一直黑屏,直到整个 for loop 执行完毕后才能出现完整视图 同时 list view 也就一次性显示了所有数据”

这应该只是个刚开始写 Android 的同学,还没有 UI 线程、子线程的概念..
Melodyer
2020-11-30 14:18:02 +08:00
@zeropercenthappy 对,他的代码应该是在 for 循环里面每次循环 sleep 了 3s 。简单点,楼主可以改为使用 Hadnler 来实现,每 3s 发送一个 message 来触发添加一个 item 的操作。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/730558

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX