FragmentStatePagerAdapter.notifyDataSetChanged不刷新页面的解决的方法
公司做医疗产品的,显示操作用的是android。所以我就用上下两个部分大致是固定的,仅仅有中间会有6个页面的切换,当中会有两个用户的切换。即普通用户和管理员用户,图片能够大致展示一下
其他页面是同样的,就这两个页面不一样,以下的是管理员用户,一想到其他页面一样的,中间就用了一个ViewPager,然后为了缓存多个页面。用到了FragmentStatePagerAdapter,然后通过setOffscreenPageLimit(6)最多缓存了6个页面,这样一下,就不用操心每一个页面的fragment的声明周期对我项目的影响了。这个界面可能没有。可是其他界面的检測什么的,线程和Ui比較复杂。easy受fragment声明周期影响而crash。
可是这个里有个奇怪的要求,管理员用户的项目设置界面的功能居然不是全的,有两个在普通用户那边。这个设计我也非常纳闷,只是,还是得做啊,之后。就遇到了题目所说的问题,notifyDataSetChanged尽管会有页面的增多和降低,可是。项目界面就是不刷新。
然后找了度娘和谷哥,出来的答案大多指向同一篇文章http://www.cnblogs.com/dancefire/archive/2013/01/02/why-notifyDataSetChanged-does-not-work.html,稍微看了一遍,照着上面方法试了。报错。依然不得其要领,然后自己去看了下源代码,攻克了。分享并记住这个问题,免得以后再犯错
先进入notifyDataSetChanged
发现这句,mObservable,看名字,观察者,应该就是用来实时监測viewPager绑定数据源的变化的。再进入notifychanged方法
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjI5NjEwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
发现一个遍历。这个遍历会去调用mObservers中的每个元素的变化。我们再进入onChanged,
到了,这里,发现onChanged仅仅是一个抽象类中的方法。,既然会调用,肯定会被重写咯,找了一圈。在viewPager中的内部内继承了。
躲的还是蛮深的,只是这还没有找到我们须要关注的地方,那就继续找,dataSetChanged
void dataSetChanged() {
// This method only gets called if our observer is attached, so mAdapter is non-null. final int adapterCount = mAdapter.getCount();
mExpectedAdapterCount = adapterCount;
boolean needPopulate = mItems.size() < mOffscreenPageLimit * 2 + 1 &&
mItems.size() < adapterCount;
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, adapterCount - 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();
}
}
这里就是我们须要关注的地方了,一看这么多。确实有点头疼。只是,我们仅仅关注重点,看第13行,有句
final int newPos = mAdapter.getItemPosition(ii.object);
这里就调用的了我们的adapter中的getItemPosition,我们再看看getItemPosition会返回什么,会接收什么,复写fragmentStatePagerAdapter中的getItemPosition方法,发现仅仅会返回父类中的方法
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjI5NjEwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
接着看父类中的方法
再看看POSITION_UNCHANGED是干嘛用的。
马丹,这下总算是明确了,这里一直return POSITION_UNCHANGED;
return一个“未改变”的标志给dataSetChanged()中,它当然打死都不更新咯。请看dataSetChanged()中的第15-17行
魂淡,居然知道原因了。那就好做了。直接将要刷新的页面 return POSITION_NONE
@Override
public int getItemPosition(Object object) {
if (object.getClass().getName().equals(ProjectFragment.class.getName())
|| object.getClass().getName().equals(ProjectFragment2.class.getName())) {
return POSITION_NONE;
}
return super.getItemPosition(object);
}
FragmentStatePagerAdapter.notifyDataSetChanged不刷新页面的解决的方法的更多相关文章
- Javascript刷新页面的几种方法
Javascript刷新页面的几种方法: window.navigate(location)location.reload()location=locationlocation.assign(loca ...
- Javascript刷新页面的八种方法
/** * Javascript刷新页面的八种方法 * 说明一下,jQuery没有发现刷新页面的方法. */ 1 history.go(0) 2 location.reload() 3 locatio ...
- JS刷新页面的几种方法(转)
Javascript刷新页面的几种方法: 1 history.go(0) 2 location.reload() 3 location=location 4 location.assign(locat ...
- Javascript刷新页面的几种方法:
Javascript刷新页面的几种方法: 1 history.go(0) 2 window.location.reload() window.location.reload(true) ...
- 24、vuex刷新页面数据丢失解决办法
刷新页面时候将state数据保存到localStorage里面: export default { name: 'App', created () { //在页面加载时读取localStorage里的 ...
- js form表单提交后如何可以不刷新页面 的解决办法
表单可实现无刷新页面提交,无需页面跳转,如下: 通过一个隐藏的iframe实现, form表单的target设置为iframe的name名称,form提交目标位当前页面iframe则不会刷新页面 &l ...
- ios开发中APP底部上滑不能调出如WiFi、蓝牙、播放等的设置页面的解决的方法
在开发的APP中我们通常通过手动底部上滑来调出WiFi.蓝牙.飞行模式等的设置页面.有时我们开发的APP无法调出. 解决的方法: 进入iPhone "设置" --> &quo ...
- c#.net防止按F5刷新页面重复提交的方法
在网上购物的过程中,提交完一个页面后,如果此时按f5刷新,则会弹出一个提示:如果继续,则会重新发送提交我们刚才提交的内容,这个问题应该规避掉,不然总是重复提交付款,那可不是件好事. 在c#.net中的 ...
- js刷新页面的几种方法
history.go(0) location.reload() location=location location.assign(location) document.execCommand('Re ...
随机推荐
- WPF中增加Month Calendar月历控件
XAML代码:(这里使用了codeproject.com网站上的一个Dll,你可以在这里下载它:http://www.codeproject.com/cs/miscctrl/MonthCalendar ...
- JavaEE下载文件名不显示中文的问题
我们在做JavaEE项目下载文件时,在我们熟悉的UTF-8编码下经常会发现文件名中文乱码.中文不显示等状况,此时,将文 件名改一下编码或许会解决这个烦恼: fileName = new String( ...
- 标签form表单里的属性简单介绍了一下
<form id="form1" name="form1" method="post" action=""> ...
- csu 10月 月赛 I 题 The Contest
Description 殷犇有很多队员.他们都认为自己是最强的,于是,一场比赛开始了~ 于是安叔主办了一场比赛,比赛有n个题目,每个题目都有一个价值Pi和相对能力消耗Wi,但是有些题目因为太坑不能同时 ...
- uvalive 6185
高斯消元,以前从来没写过,今天的模拟比赛里面,添琦给了我一个模板! 虽然是个裸的,但是因为从来没写过,一个小细节竟然搞了我几个小时: 终于最后在小珺同志的帮助下成功a掉了,太开心了! 存一下,作为模板 ...
- 使用eclipse开发webService很简单
原文转自:http://blog.csdn.net/guo_rui22/article/details/6253745 使用Eclipse生成一个WebService应用 1.创建一个Dynamic ...
- WebBrowser控件跨域访问页面内容
原文出处 :http://blog.csdn.net/nocky/article/details/6056802 源码出处:http://www.codecentrix.com/blog/wnd2do ...
- UIImagePickerController 如何显示中文界面
1: 添加中文的 Localizations Project --> Info --> Localizations 添加 "Chinese(Simplified)" ...
- Unity3D插件之Easy Touch 3.1(1): Easy Joystick
先看官方介绍:https://www.assetstore.unity3d.com/#/content/3322 (Allows you to quickly and easily develop a ...
- 【转】windows7 64位系统认不出8g内存显示只有3G可用
原文网址:http://www.jb51.neos/windows/93721.html 我的电脑安装的是Win7 64位系统,当时内存是用的8G的,系统里面显示出来只有3.00G可用,真是崩溃啊 ...