从源码分析PagerAdapter notifyDataSetChanged刷新数据的最佳姿势

    最近在做项目的时候有个需求是ViewPager分为2页内容,2个页面都有用户的一些信息,比如vip状态等。在当前页可以充值vip,所以理所当然的,在充值成功后当前页面用户的vip状态发生变化,需要刷新。

    直接撸代码,充值成功后直接调用了adapter的notifyDataSetChanged方法,发现页面没有修改;打log也发现页面没有刷新的操作,网上大概找了一些资料,有个方法是:

如上,重写getItemPostion并返回POSITION_NONE,问题解决了。不过总感觉稀里糊涂的,那想知道到底怎么回事,唯有翻源码了。(如果你的页面比较简单,比如就返回一个TextView、ImageView那么到这里基本已经解决了你的问题。但是如果你的界面较为复杂,请继续看下去。如果想直接找到解决方法请跳过分析源码这部分看文末。)

    我们直接从adapter的notifyDataSetChanged方法开始,直接点进去:

就简单的这么几行代码,不过大体一看基本是传统的观察者模式;既然是观察者,那咱们就去看看这个mViewPagerObserver是在哪里注册观察的,PageAdapter中有个方法:

通过这个方法设置了观察者,这个方法是在ViewPager中去调用的:

其他内容我们忽略,只看红框内。在serAdapter方法中,创建了观察者,并设置到PagerAdapter中。那么代码自然就来到PagerObserver类中的onChanged方法中

直接调用了dataSerChanged方法,跟进

由于该方法比较长,我们删除一些不太相干的代码,看主要内容;我们先看一下那行注释,意思大概是说只有注册了观察者才会调用这个方法,分析源码时注释是个好东西。向下

POSITION_UNCHANGED直接continue,所以如果需要的话也可以这样去设置,再下边POSITION_NONE它可不是直接continue了,而是先回调了distoryItem并将needPopulate(是否需要填充)置为true,记住这个变量;继续往下走最后会判断needPopulate;

上边已经将它置为true所以会走进来,来到setCurrentItemInternal方法,在这个方法中,根据我们要解决的问题主要是调用了populate方法,然后主要是调用了addNewItem方法将新的item创建。这里就不贴过多的源码了。

    所以我们总结出来如果getItemPostion返回了POSITION_NONE那么会先distoryItem然后在新建,那如果页面较为复杂的话,作为一名合格的程序员我们知道肯定是比较浪费性能。

    最后的解决方法:

我们在instantiateItem也就是item创建的时候将后面需要更新的view(不是item整体,可以是具体的某个TextView、ImageView等)添加tag,然后在需要更新的时候通过ViewPager获取这个tag来获取要更新的view,然后重新设置数据等其他操作。这样会节省很多性能问题。

    好啦,今天的内容就分享到这里,有问题请大家指正,如果本篇内容正好帮你解决了问题或觉得文章内容不错帮忙点个赞。感谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值