Android -- 处理ViewPager的notifyDataSetChanged无刷新
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 range
newCurrItem = 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;
@Override
public void notifyDataSetChanged() {
mChildCount = getCount();
super.notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
if ( mChildCount > 0) {
mChildCount --;
return POSITION_NONE;
}
return super.getItemPosition(object);
}
}
我是天王盖地虎的分割线
Android -- 处理ViewPager的notifyDataSetChanged无刷新的更多相关文章
- ##解决 ViewPager 调用 notifyDataSetChanged()无刷新:原理、解决办法##
一.原理 转自:http://www.cnblogs.com/maoyu417/p/3740209.html 转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分 ...
- Android viewPage notifyDataSetChanged无刷新
转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分享.其中一位同学分享了一下自己在解决问题过程中的一些心得体会,感觉受益匪浅.整理出来,分享给大家. 建议使用自 ...
- android listview用adapter.notifyDataSetChanged()无法刷新每项的图标
http://blog.csdn.net/caizhegnhao/article/details/41318575 今天在开发中遇到一个很奇怪的listview的问题. 这个问题情景是我的应用需要做一 ...
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
ViewPager是android-support-v4.jar包中的一个系统控件,继承自ViewGroup,专门用以实现左右滑动切换View的效果,使用时需要首先在Project->prope ...
- ListView动态刷新adapter.notifyDataSetChanged()无反应
前段时间在做一个动态刷新ListView(模拟聊天),遇到一个问题,调用notifyDataSetChanged()方法,数据源已经存在但是并没有动态刷新! 首先我们需要了解notifyDataSet ...
- Android PullToRefresh (GridView 下拉刷新上拉加载)
做这个需要自己去git hub上下载个pull-to-refresh 里面有个library为依赖包自己导到自己的项目中 (下载地址:https://github.com/chrisbanes/And ...
- Android listview viewpager解决冲突 滑动
Android listview viewpager滑动 跳动 冲突解决 ListView中嵌套ViewPage有或者滑动手势冲突解决 在listview 上使用 addHeaderView 在第 ...
- 【JS】ajax 实现无刷新文件上传
一.摘要 最近在做个东西,需要实现页面无刷新文件上传,目前看到的方法有两种 1) 通过隐藏iframe 实现页面无刷新,适用于不关心上传结果 <form target="hiddenF ...
- 无刷新更新listview
闲来无事,写点水文吧!有用得着的可以参考下,无刷新更新listview是什么意思呢?举个例子,在订单类listview列表中,常常会有各种订单状态,拿商城类app来说,会有待付款,待收货,确认收货等等 ...
随机推荐
- 关于dubbo服务的xml配置文件报错的问题
在配置dubbo服务的过程中,经常会遇到虽然程序能够跑起来,但是配置文件一堆红叉,虽然不影响功能,但是确实很让人恶心. 报错信息如下: Multiple annotations found at th ...
- #pragma pack(n)的使用
在缺省情况下,编译器为了让程序跑得跟快,减少CPU读取数据的指令周期,对结构体的存储进行了优化, 比如:如下结构体 struct s { char ch; int i; }; 虽然变量ch本身只有1个 ...
- MongoDB中的变更通知
MongoDb 3.6中引入了一个新特性change stream,简单的来说就是变更通知,它提供了一个接口允许应用实时获取数据库变更,这个在ETL.数据同步.数据迁移.消息通知等方面非常有用. 使用 ...
- STM32 GPIO fast data transfer with DMA
AN2548 -- 使用 STM32F101xx 和 STM32F103xx 的 DMA 控制器 DMA控制器 DMA是AMBA的先进高性能总线(AHB)上的设备,它有2个AHB端口: 一个是从端口, ...
- Nginx FastCGI的运行原理
http://www.cnblogs.com/yinshoucheng-golden/p/6474034.html
- 用DELPHI 开发压缩、解压、自解压、加密
引 言:在日常中,我们一定使用过WINZIP.WINRAR这样的出名的压缩软件,就是我们开发软件过程中不免要遇到数据加密.数据压缩的问题!本文中就这一技术问题展开探讨,同时感谢各位网友的技巧,在我每次 ...
- Windows Phone本地数据库(SQLCE):9、Connection Strings(翻译) (转)
这是“windows phone mango本地数据库(sqlce)”系列短片文章的第八篇. 为了让你开始在Windows Phone Mango中使用数据库,这一系列短片文章将覆盖所有你需要知道的知 ...
- ZServer4D开源项目
ZServer4D开源项目 ZServer4D 是一套从商业项目剥离而出的云服务器中间件,可以承载百万级的分布式负载服务,并且支持IoT及内网穿透. 作者将它开源了 https://github.co ...
- 从CRITS发展历史解读结构框架
Michael Goffin 是MITRE公司的一名员工,在其博客中介绍了Crits 的发展历史.原文地址例如以下: CRITs: Collaborative Research Into Threat ...
- Linux进程ID号--Linux进程的管理与调度(三)
转自:http://blog.csdn.net/gatieme/article/category/6225543 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux- ...