ViewPager notifyDataSetChanged 在一些机型上无法生效的原因

1,362 阅读1分钟

ViewPager 在页面异步加载的时候,会如下图所示处理这块代码,但是却在部分机型上会发现一些页面没有刷新,而是会重复展示了。

为什么notifyDataSetChanged会不生效呢?

notifyDataSetChanged 里发生了什么?

pageAdapter的notifyDataSetChanged最终会调用到ViewPager的dataSetChanged方法,我们关注两点,一是如果mItems.size=0则notifyDataSetChanged是不生效的;二是如果newPos为POSITION_UNCHANGED 则循环每次都跳过,notify也不会生效,而newPos如果adapter没有复写getItemPosition默认返回的就是POSITION_UNCHANGED。

我们反推下现象出现的原因,既然没有复写getItemPosition方法,然后又一部分机型是正常的,只能说明mItems.size=0。因为如果这个不为0,就一定会出现重复,因为这是个延迟调用,那么为什么mItems.size=0呢,我们看下setAdapter里发生了什么。

setAdapter里发生了什么

看上面这块代码,因为mFirstLayout是默认是true,因此最终是走到了requestLayout,这是一个异步的操作。

最终在onMeasure中mItems被add了fragment。 所以如果有些机型requestLayout在异步notifyDataSetChanged后调用就不会发生这个问题,否则就会出现这个问题。多说一句,因为这个异步调用只有第一次会很慢,后面会很快,requestLayout这个步骤是系统决定的,但是在华为手机上出现的概率挺高的,感觉应该是华为机型requestLayout调用了就立马触发了的感觉。

总结

综上,ViewPager的想通过notifyDataSetChanged达到刷新页面的目的,必须要复写getItemPosition方法,否则是无法生效的。