zoukankan      html  css  js  c++  java
  • 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方法

    发现一个遍历。这个遍历会去调用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);
        }


  • 相关阅读:
    Python3爬虫之爬取某一路径的所有html文件
    python获取数据网页数据并创建文件夹保存(基于python3.6)
    Python 爬取单个网页所需要加载的地址和CSS、JS文件地址
    java的关闭钩子(Shutdown Hook)
    如何形象的解释 webhook 这个词
    Webhook
    什么是webhook
    瞎折腾之Webhooks
    Java-马士兵设计模式学习笔记-观察者模式-读取properties文件,动态增加观察者
    怎么解决重装系统后“我的文档”拒绝访问(更改权限就可以了)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5330584.html
Copyright © 2011-2022 走看看