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来说,会有待付款,待收货,确认收货等等 ...
随机推荐
- String和StringBuilder、StringBuffer的区别?
估计很多Java初学者在学习Java的过程中都会遇到这个问题,那就是String,StringBuilder,StringBuffer这三个类之间有什么区别?今天在这里整理一下,希望对大家有帮助哈.如 ...
- 吴恩达-coursera-机器学习-week7
十二.支持向量机(Support Vector Machines) 12.1 优化目标 12.2 大边界的直观理解 12.3 数学背后的大边界分类(选修) 12.4 核函数1 12.5 核函数2 12 ...
- JavaScript获取事件对象和目标对象
在JavaScript开发中,经常需要获取触发某个事件的目标对象.让后根据目标对象进行不同的业务处理.下面展示通过JavaScript获取触发事件的事件目标对象.如下: Js代码 1 2 3 4 5 ...
- HTML5定稿了,终于有一种编程语言开发的程序可以在Android和IOS两种设备上运行了
2007 年 W3C (万维网联盟)立项 HTML5,直至 2014 年 10 月底,这个长达八年的规范终于正式封稿. 过去这些年,HTML5 颠覆了 PC 互联网的格局,优化了移动互联网的体验,接下 ...
- stm-ledstrip : Driver and test routine for WS2811 RGB-LED
stm-ledstrip : Driver and test routine for WS2811 RGB-LED #include "ws2812.h" #include < ...
- STM32F2x Is it possible to request multiple DMA streams with single request
I want to setup an application, where a single trigger-factor (compare-match of a timer) shall reque ...
- [Go] 正则表达式 示例
package main import "bytes" import "fmt" import "regexp" func main() { ...
- HTML一些标签注意事项
最近在IE10下运行一个以前的做web系统发现了两个小问题: 一.图片上使用"alt"属性来添加一些文字提示信息在IE10下无法正常显示出来 上网查了一下原因:原来是现在一些较新的 ...
- 报错:TargetException, 非静态方法需要一个目标
如果实例为null,调用实例方法会报如上错. 解决办法: 检查实例是否为null,考虑什么情况下实例为null,然后排除实例为null的情况.
- smartsvn学习(一)Xcode下svn客户端使用指南
http://smartsvn.com/features 说明 场景 执行步骤 创建新项目 一,二,三,四 下载项目 一,二,四 代码提交 五 代码更新 六 一,打开SCM 在xcode中,点击菜单: ...