Viewpager在调用notifyDataSetChanged()时,界面无刷新

Viewpager在调用notifyDataSetChanged()时,界面无刷新,它确实影响我们功能的实现了。可能选择为Viewpager重新设置一遍适配器adapter,达到刷新的目的。但是这种方法在大多数情况下,是有问题的。

查看方法

super.notifyDataSetChanged()调用的是PagerAdapter.notifyDataSetChanged()

/*** This method should be called by the application if the data backing this adapter has changed* and associated views should update.*/public void notifyDataSetChanged() {mObservable.notifyChanged();}

注释里说到,当附加在适配器上的数据发生变化时,应该调用该方法刷新数据。该方法调用了一个mObservable .notifyChanged();

我们继续跟进这个方法,进入DataSetObservable类中,发现这样一段代码:

/*** Invokes {@link DataSetObserver#onChanged} on each observer.* Called when the contents of the data set have changed.  The recipient* will obtain the new contents the next time it queries the data set.*/public void notifyChanged() {synchronized(mObservers ) {// since onChanged() is implemented by the app, it could do anything, including// removing itself from {@link mObservers} - and that could cause problems if// an iterator is used on the ArrayList {@link mObservers}.// to avoid such problems, just march thru the list in the reverse order.for (int i = mObservers .size() - 1; i >= 0; i--) {mObservers.get(i).onChanged();}}}

这都不是重点,重点我们来看这个mObservers的类型是一个抽象类DataSetObserver,里面只有两个未实现的方法,都有谁使用了这个抽象类呢,其中我们发现了Viewpager的身影。进入viewpager,我们终于找到了viewpager中控制数据变更的重点方法dataSetChanged ,这个方法如下:

void dataSetChanged () {// This method only gets called if our observer is attached, so mAdapter is non-null.boolean needPopulate = mItems .size() < mOffscreenPageLimit * 2 + 1 &&mItems.size() < mAdapter.getCount();int newCurrItem = mCurItem ;boolean isUpdating = false;for (int i = 0; i < mItems.size(); i++) {final ItemInfo ii = mItems .get(i);final int newPos = mAdapter.getItemPosition(ii.object );if (newPos == PagerAdapter.POSITION_UNCHANGED ) {continue;}if (newPos == PagerAdapter.POSITION_NONE) {mItems.remove(i);i--;if (!isUpdating) {mAdapter.startUpdate( this);isUpdating = true;}mAdapter.destroyItem( this, ii.position , ii.object);needPopulate = true;if (mCurItem == ii.position ) {// Keep the current item in the valid rangenewCurrItem = Math. max(0, Math.min(mCurItem, mAdapter.getCount() - 1));needPopulate = true;}continue;}if (ii.position != newPos) {if (ii.position == mCurItem ) {// Our current item changed position. Follow it.newCurrItem = newPos;}ii. position = newPos;needPopulate = true;}}if (isUpdating) {mAdapter.finishUpdate( this);}Collections. sort(mItems, COMPARATOR);if (needPopulate) {// Reset our known page widths; populate will recompute them.final int childCount = getChildCount();for (int i = 0; i < childCount; i++) {final View child = getChildAt(i);final LayoutParams lp = (LayoutParams) child.getLayoutParams();if (!lp.isDecor ) {lp. widthFactor = 0.f;}}setCurrentItemInternal(newCurrItem, false, true);requestLayout();}}

重点看这样一行代码:

final int newPos = mAdapter.getItemPosition(ii.object );if (newPos == PagerAdapter.POSITION_UNCHANGED ) {continue ;}

Called when the host view is attempting to determine if an item’s position has changed. Returns POSITION_UNCHANGED if the position of the given item has not changed orPOSITION_NONE if the item is no longer present in the adapter.

The default implementation assumes that items will never change position and always returnsPOSITION_UNCHANGED.

意思是如果item的位置如果没有发生变化,则返回POSITION_UNCHANGED。如果返回了POSITION_NONE,表示该位置的item已经不存在了。默认的实现是假设item的位置永远不会发生变化,而返回POSITION_UNCHANGED

解决方案

所以我们可以尝试着修改适配器的写法,覆盖getItemPosition()方法,当调用notifyDataSetChanged时,让getItemPosition方法人为的返回POSITION_NONE,从而达到强迫viewpager重绘所有item的目的。

class SearchAdapter extends PagerAdapter {private int mChildCount = 0;@Overridepublic void notifyDataSetChanged() {         mChildCount = getCount();super.notifyDataSetChanged();}@Overridepublic int getItemPosition(Object object)   {          if ( mChildCount > 0) {mChildCount --;return POSITION_NONE;}return super.getItemPosition(object);}}

我是天王盖地虎的分割线

本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4232614.html,如需转载请自行联系原作者

Android -- 处理ViewPager的notifyDataSetChanged无刷新相关推荐

  1. ##解决 ViewPager 调用 notifyDataSetChanged()无刷新:原理、解决办法##

    一.原理 转自:http://www.cnblogs.com/maoyu417/p/3740209.html 转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分 ...

  2. android 无刷新 好友,Android viewPage notifyDataSetChanged无刷新

    转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分享.其中一位同学分享了一下自己在解决问题过程中的一些心得体会,感觉受益匪浅.整理出来,分享给大家. 建议使用自 ...

  3. android中viewpager+fragment,ViewPager和Fragment一篇就够了

    ViewPager显示多Fragment使用问题 前言:每当使用ViewPager时,对于选用什么适配器,缓存多少页面,是否需要懒加载以及Fragment的数据刷新经常会有些疑问,网络上的答案很多,但 ...

  4. 浅谈移动端页面无刷新跳转问题的解决方案

    最近开发微信公众号,用的框架是 一般的 UI,但是涉及到多页面之间的相互跳转的问题,降低了浏览器的性能,用户体验特别不好,卡顿,不流畅,因此不采用传统的页面跳转方式,看到不少手机网页开发的框架都都是在 ...

  5. 微信小程序手把手教你实现类似Android中ViewPager控件效果

    微信小程序手把手教你实现类似Android中ViewPager控件效果 前言 需求分析 头部TAB 滑动的内容部分 最终版本 尾巴 前言 在做Android开发的时候,ViewPager是开发者使用频 ...

  6. android 今日头条加载动画,Android 仿今日头条简单的刷新效果实例代码

    点击按钮,先自动进行下拉刷新,也可以手动刷新,刷新完后,最后就多一行数据.有四个选项卡. 前两天导师要求做一个给本科学生预定机房座位的app,出发点来自这里.做着做着遇到很多问题,都解决了.这个效果感 ...

  7. 六步使用ICallbackEventHandler实现无刷新回调

    AJAX技术所提倡的无刷新回调,在原来的技术中需要写大量的JavaScript代码或使用一些AJAX框架,使得开发效率和可维护性大大降低.其实ASP.NET2.0中,已经提供了这样的接口,这就是ICa ...

  8. Ajax实现无刷新三联动下拉框

    1.html代码 <HTML>     <HEAD>         <title>Ajax实现无刷新三联动下拉框</title>         &l ...

  9. Ajax无刷新实现图片切换特效

    1.页面cs代码 using System; using System.Data; using System.Configuration; using System.Web; using System ...

最新文章

  1. SAP PP使用ECR去修改Recipe主数据,报错:Generation not supported for change object
  2. .net core 与ELK(2)安装Elasticsearch可视化工具
  3. 树莓派第一次开机自动连接WIFI(不用显示屏方法)
  4. sqlserver两个日期之间的年数_SQL语句计算两个日期之间有多少个工作日的方法
  5. 百度关键词点击ios_百度推广关键词点击价格高,如何处理?
  6. php url 合法字符串_PHP函数补完:http_build_query()构造URL字符串
  7. JS学习总结(5)——循环语句
  8. 水氢发动机应该叫氢能发动机、铝水制氢发动机
  9. python colour-science 绘制CIE 1976色度图
  10. 笔记本电脑触摸板操作
  11. android 126邮箱格式,如何在Android系统邮件应用程序中添加帐户(默认POP3)
  12. CSPS2019Day1T2(括号树)题解
  13. C语言实现倒计时关机程序(goto语句、strcpm函数、system函数)
  14. 从小学到大学到出社会以后我的感受(出社会时间不长)
  15. go 运行代码遇到的问题(同一个包,不同包 之间的引用报错)
  16. 【友盟+】国庆假期旅游类APP使用报告(下)
  17. 【网络编程开发系列】好端端的MQTT-broker重新部署后居然出现TLS握手失败了
  18. 【信号调理】ADC保护电路/ADC缓冲器
  19. centos7的syslog知识点
  20. 怎么选房能让房子升值20倍?这些因素很重要

热门文章

  1. ROS学习笔记-ROS语音识别与语音输出[2]
  2. ROS 常用命令汇总(不定期更新)
  3. 十大排序算法之快速排序(两种方法)
  4. 通过LDAP验证Active Directory服务
  5. Can't find dependent libraries
  6. C#中读取带有Xmlns命名空间的XML文件
  7. Linux字符设备与块设备的区别与比较
  8. Tomcat 配置 Context
  9. ZOJ-2770 Burn the Linked Camp 差分约束
  10. u-boot-2012.07 for FL2440