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 ...
随机推荐
- POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数
题目链接: http://poj.org/problem?id=2299 题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数. 利用归并排序求解,内存和耗时都比较少, 但是有 ...
- SQL Server 2008 R2 主从数据库同步设置
一.准备工作: 主数据库服务器: OS:Windows Server 2008 R2 DB: SQL Server 2008 R2 Hostname : CXMasterDB IP: 192.1 ...
- 2、.net NVelocity中原生javascript ajax封装使用
在页面上,我们经常会遇到局部刷新的例子,这个时候,就需要用到ajax, 因为很多代码都是公用的,所以我们想到了,将代码封装,简化了使用,减少了冗余 javascript ajax代码如下: var x ...
- IP,TCP,UDP Checksum校验
IP数据报的校验: IP数据报只需要对数据头进行校验,步骤如下: 将接收到的数据的checksum字段设置为0 把需要校验的字段的所有位划分为16位(2字节)的字 把所有16位的字相加,如果遇到进位, ...
- Ubuntu 安装 JDK 7 / JDK8 的两种方式
ubuntu 安装jdk 的两种方式: 1:通过ppa(源) 方式安装. 2:通过官网下载安装包安装. 这里推荐第1种,因为可以通过 apt-get upgrade 方式方便获得jdk的升级 使用pp ...
- Word续上表
选中表格的下半部分(全部下半部分),然后按ctrl+shift+enter,这样就换行了.
- uva 11992 - Fast Matrix Operations
简单的线段树的题: 有两种方法写这个题,目前用的熟是这种慢点的: 不过不知道怎么老是T: 感觉网上A过的人的时间度都好小,但他们都是用数组实现的 难道是指针比数组慢? 好吧,以后多用数组写写吧! 超时 ...
- hdu 4762 && 2013 ACM/ICPC 长春网络赛解题报告
这次的答案是猜出来的,如果做得话应该是应该是一个几何概型的数学题: 答案就是:n/(m^(n-1)); 具体的证明过程: 1.首先枚举这M个点中的的两个端点,概率是:n*(n-1); 2.假设这个蛋糕 ...
- HTML5 Geolocation
http://diveintohtml5.info/geolocation.html http://msdn.microsoft.com/en-us/library/windows/apps/hh44 ...
- asp.net 163邮件发送
<table id="> <tr> <td style="width: 393px"> 收信:<asp:TextBox ID=. ...