FragmentStatePagerAdapter.notifyDataSetChanged不刷新页面的解决办法

公司做医疗产品的,显示操作用的是android,所以我就用上下两个部分大致是固定的,只有中间会有6个页面的切换,其中会有两个用户的切换,即普通用户和管理员用户,图片可以大致展示一下

其它页面是相同的,就这两个页面不一样,下面的是管理员用户,一想到其它页面一样的,中间就用了一个ViewPager,然后为了缓存多个页面,用到了FragmentStatePagerAdapter,然后通过setOffscreenPageLimit(6)最多缓存了6个页面,这样一下,就不用担心每个页面的fragment的声明周期对我项目的影响了,这个界面可能没有,但是其它界面的检测什么的,线程和Ui比较复杂,容易受fragment声明周期影响而crash。

但是这个里有个奇怪的要求,管理员用户的项目设置界面的功能竟然不是全的,有两个在普通用户那边,这个设计我也很纳闷,不过,还是得做啊,之后,就遇到了题目所说的问题,notifyDataSetChanged虽然会有页面的增多和减少,但是,项目界面就是不刷新。

然后找了度娘和谷哥,出来的答案大多指向同一篇文章http://www.cnblogs.com/dancefire/archive/2013/01/02/why-notifyDataSetChanged-does-not-work.html,略微看了一遍,照着上面方法试了,报错,依旧不得其要领,然后自己去看了下源码,解决了,分享并记住这个问题,免得以后再犯错

先进入notifyDataSetChanged

发现这句,mObservable,看名字,观察者,应该就是用来实时监测viewPager绑定数据源的变化的,再进入notifychanged方法

发现一个遍历,这个遍历会去调用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方法,发现只会返回父类中的方法

接着看父类中的方法

再看看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);
    }
时间: 2024-10-29 15:51:00

FragmentStatePagerAdapter.notifyDataSetChanged不刷新页面的解决办法的相关文章

Sitemesh排除Exclude不装饰特定页面的解决办法

有时候项目中有些文件不需要Sitemesh装饰,例如Error.htm, Error.jsp, OnlineHelp.htm等等.但是用Sitemesh的Exclude不管用,用Printable也不管用: 因为Sitemesh装饰的排除路径是虚拟路径而非实际路径.Sitemesh是根据URL来进行装饰Decoration的.最后的解决办法是:如果我们不想让Sitemesh对OnlineHelp.htm进行装饰,那就在这个文件的头加上这个: 然后在decorators.xml里面配置一下: 最后

vuex页面刷新数据丢失的解决办法

在vue项目中用vuex来做全局的状态管理, 发现当刷新网页后,保存在vuex实例store里的数据会丢失. 原因: 因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值初始化 解决思路: 将state的数据保存在localstorage.sessionstorage或cookie中(三者的区别),这样即可保证页面刷新数据不丢失且易于读取. localStorage: localStorage的生命周期是永久的,关闭页面或浏览器之

vue项目打包之后页面空白解决办法

之前项目遇到个情况,npm run build打包之后上传到服务器后,index.html打开一片空白,资源都加载了,但是就是不显示. 然后百度找了原因,修改了两处地方 一.修改 assetsPublicPath 在config/index.js里面,有个 assetsPublicPath 属性,源码是'/',修改成'./',加个点 assetsPublicPath: '/',二.路由模式将histroy改成hash模式,起初 mode:'history' const router = new

zencart后台管理中选项名称和选项内容和属性控制页面出错解决办法 WARNING: An Error occurred, please refresh the page and try again

后台管理中选项名称和选项内容和属性控制出现以下错误的解决办法WARNING: An Error occurred, please refresh the page and try again zen cart v1.5.1 的一个bug,重新下载更新的zencart安装包,然后取出以下三个文件替换:admin/attributes_controller.phpadmin/option_names_manager.phpadmin/option_values_manager.php 或者手工修复如

jsp页面中文解决办法

关于JSP页面之间传值的中文乱码总结 用过滤器来解决JSP中文乱码问题 URLEncoder.encode与URLDecoder.docode传递中文参数编码与解码 URLEncoder与URLDecoder的使用 ------------------------------------------------------------------------------------------------------- 本部分转载自:http://blog.csdn.net/gongxifaca

bootstrap打开模态modal窗口引起页面抖动解决办法

在使用bootstrap的modal模态窗口组件时,触发后会发现页面有抖动现象.这是因为它隐藏了浏览器滚动条,页面就相当于变宽了,关闭模态窗口后,页面又出现滚动条,页面又变窄了,这一伸一缩就会使页面产生抖动现象.我的解决方法很简单,就是干掉隐藏滚动条的代码.总共删除bootstrap.js文件中6行代码就可以了. 以bootstrap3.3.6版本中未压缩的bootstrap.js文件为例. 第一处在971行左右,删除这3句 this.checkScrollbar() this.setScrol

网站被***导致百度快照被劫持跳转到×××页面的解决办法

近期受世界杯的影响,我们Sinesafe接过很多中小企业网站频繁的被×××***篡改了快照内容的网站安全问题导致打开网站被提示×××页面,在搜索引擎中会被提示百度网址安全中心提醒您:该页面可能已被非法篡改! 主要客户网站问题基本都是反复性质的篡改,手动清理删除掉代码只能解决当前问题,没过几天就又被篡改了内容,而且经常是篡改首页顶部的代码. 1.网站快照被劫持问题分析与解决方案处理过程 下面我们分析下客户网站,客户是Linux系统的单独服务器,网站采用的是discuz论坛程序+uchome (PH

三种上传文件不刷新页面的方法讨论:iframe/FormData/FileReader

发请求有两种方式,一种是用ajax,另一种是用form提交,默认的form提交如果不做处理的话,会使页面重定向.以一个简单的demo做说明: html如下所示,请求的路径action为"upload",其它的不做任何处理: <form method="POST" action="upload" enctype="multipart/form-data"> 名字 <input type="text&q

FineUI官方论坛出现空白页的解决办法!

问题描述:访问FineUI官方论坛或者QQ互联登陆时,可能会出现空白页面! 解决办法:清空站点Cookie! 下面分别介绍Chrome.Firefox.IE下清空站点Cookie的方法: Firefox: Chrome: IE: ----- 三生石上