请教一下, Android 里的 ListView 如何实时更新数据并逐条显示? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ww050312
V2EX    问与答

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

  •  
  •   ww050312 2020-11-30 12:58:36 +08:00 2549 次点击
    这是一个创建于 1777 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想做类似微信对话那种形式的 listview,但是是后台接受到十几个数据后依次添加到 arraylist 里,每次 arraylist.add(item)之后就调用 notifyDataSetChanged()方法想让视图上出现新的一行,3s 之后再添加第二行,可是用 for loop 之后发现就算我在每次 notifyDataSetChanged 之后延迟 3s 也会变成 3s 之后所有数据一次性出现在视图上……已经彻底懵了。请问一下有什么可行的方式实现吗?
    第 1 条附言    2020-11-30 15:13:26 +08:00
    已经 ok 了 感谢
    32 条回复    2020-12-01 09:33:47 +08:00
    ww050312
        1
    ww050312  
    OP
       2020-11-30 13:10:43 +08:00
    upup
    ww050312
        2
    ww050312  
    OP
       2020-11-30 13:10:53 +08:00
    upupup
    SelectLanguage
        3
    SelectLanguage  
       2020-11-30 13:24:08 +08:00
    有刷新单条数据的方法
    kop1989
        4
    kop1989  
       2020-11-30 13:30:42 +08:00
    意思是,不管真实的数据来多少条。ListView 你也想每隔 3 秒冒出一条来?

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

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

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

    这应该只是个刚开始写 Android 的同学,还没有 UI 线程、子线程的概念..
    Melodyer
        20
    Melodyer  
       2020-11-30 14:18:02 +08:00
    @zeropercenthappy 对,他的代码应该是在 for 循环里面每次循环 sleep 了 3s 。简单点,楼主可以改为使用 Hadnler 来实现,每 3s 发送一个 message 来触发添加一个 item 的操作。
    Melodyer
        21
    Melodyer  
       2020-11-30 14:18:34 +08:00
    @Melodyer Hadnler --> Handler
    chniccs
        22
    chniccs  
       2020-11-30 14:24:47 +08:00
    ListView 已经不推荐使用了,推荐使用 RecycleView 可以局部刷新,另外你调用 notifyDataSetChanged 之后再延时 3 秒,这是在主线程中执行的吧?这样操作是阻塞了主线程了,所以你屏幕会卡住,延时操作需要在子线程中执行。然后到主线程中执行数据刷新。
    aerzha
        23
    aerzha  
       2020-11-30 14:30:31 +08:00
    维护一个消息队列(因为可能本次没发完下次的又来了),使用 handler postMessageDelay 定时发送一条消息,handleMessage 中从消息队列里取出一条(注意同步问题),然后插入到 listview 中,再 handler postMessageDelay 。。。。

    另外,推荐使用 recyclerView,直接单条数据插入,不用重新 notifydatasetchanged
    ww050312
        24
    ww050312  
    OP
       2020-11-30 14:35:20 +08:00
    @aerzha 枯了 我都不知道有这个东西 单纯 follow 我们 prof 教的东西= = 顺便问下我是自己重写的 adaptor,如果换 recycleView 的话 adaptor 变化大吗?
    aerzha
        25
    aerzha  
       2020-11-30 14:47:44 +08:00
    @ww050312 额,recyclerView 的用法, 在 Android 里算是最基础的东西了,随便网上扒篇文章,几分钟就能撸个 demo 了,adapter 的话,要使用 RecyclerView.Adapter 了
    zeropercenthappy
        26
    zeropercenthappy  
       2020-11-30 15:01:38 +08:00
    都搞错了重点了..楼主现在的问题不是 ListView 还是 RecyclerView 的问题,而是如何做到延时 3s 取数据而不阻塞主线程的问题。

    楼上说的 Handler 是可行的,但是就为了这一点需求未免有点太麻烦,所以你就老老实实用我上面说的 CountDownTimer 来做就行了,把这个作业完成了之后再去研究别人说的这些东西吧
    v2xiaowen
        27
    v2xiaowen  
       2020-11-30 15:11:10 +08:00 via Android
    3 秒给 list 里 add 一个数据
    ww050312
        28
    ww050312  
    OP
       2020-11-30 15:13:01 +08:00
    @zeropercenthappy 谢啦!已经成功了
    stfu
        29
    stfu  
       2020-11-30 16:10:53 +08:00
    @zeropercenthappy LZ 应该本身就了解 Handler 了,你拿个封装的新东西给他他更难受吧。。 而且用 Handler 比较能让新手感受到业务数据的走向。
    PS LZ05 年?建议找一个 25 岁+的前辈问问较为正确的学习路径,初步判断这个年龄学 Android 和所在做的 demo,是一条错误的路径。
    zeropercenthappy
        30
    zeropercenthappy  
       2020-11-30 16:24:13 +08:00   1
    @stfu CountDownTimer 本质也是用 Handler 实现的。
    当然本着学习的角度来说你是对的,只是我看 LZ 一脸懵的样子,再看看楼上的兄弟都扯到天边了,为了避免楼主 30 分钟 Android 开发从入门到放弃,先把解决方案给了先 haha 。
    PS:不管你是学校的作业还是自己的兴趣,欢迎入坑 Android 开发。
    ww050312
        31
    ww050312  
    OP
       2020-11-30 17:56:20 +08:00
    @stfu 啊这就是我们学校的入门安卓课(
    @zeropercenthappy 嗯 谢谢
    chenjiajia9411
        32
    chenjiajia9411  
       2020-12-01 09:33:47 +08:00
    如果愿意学 Kotlin,这个需求很快就撸出来了;即使来不及(看起来只要完成课上任务就行了),花半小时看看[Paging]( https://developer.android.com/topic/libraries/architecture/paging)怎么用也能做出来了……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     831 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 21:06 PVG 05:06 LAX 14:06 JFK 17:06
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86