详解ViewPager调用FragmentPagerAdapter.notifyDataSetChanged()不能更新Fragment

转载 2016年08月30日 12:08:03

第一部分:现象出现的原因

代码默认实现如此。
FragmentPagerAdapter调用notifyDataSetChanged后,执行mObservable.notifyChanged()。mObservable对象的初始化,是在ViewPager调用setAdapter时被赋值的,对应的类叫PagerObserver。PagerObserver的dataSetChanged方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
for(inti = 0; i < mItems.size(); i++) {
            finalItemInfo ii = mItems.get(i);
            finalint 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;
            }
        }

PagerAdapter的默认getItemPosition实现是 return POSITION_UNCHANGED。所以调用notifyDataSetChanged方法不会刷新Fragment。

第二部分:解决办法

为了让Fragment重新绘制,必须重载FragmentPagerAdapter的getItemPositon方法并修改为return POSITION_NONE。这样之前所有的Fragment都会被detach掉。

1
2
3
4
@Override
    publicint getItemPosition(Object object) {
        returnPOSITION_NONE;
    }

如果你按上面的步骤做了,而且调用notifyDataSetChanged时候,list数据位空,那么结果是你希望看到的。但是如果list的数据在原有的基础上做了修改,但是结果你看到的Fragment上显示的信息还是之前的数据。

第三部分:Fragment不刷新的原因

如第二部分描述,旧的Fragment都会被detach掉,但是它并没有被distory掉,而是被保存下来了,保存时候存储的tag来源如下代码:

1
2
3
privatestatic String makeFragmentName(intviewId, longid) {
        return"android:switcher:" + viewId + ":"+ id;
    }

刷新后调用FragmentPagerAdapgter的instantiateItem方法,会通过findFragmentByTag找到被detach掉的Fragment,然后再执行该Fragemnt的attach方法,最后再次执行Fragment的生命周期,所以你看到的Fragment上面的数据还是老数据。

第四部分:解决办法

如第三部分描述,如果Fragment你是通过getItem方法中去new一个Fragment出来,然后数据通过setArgument设置进去的。那么再次执行改Fragment的attach方法后,拿到的数据还是老数据。解决版本就是在instantiateItem方法中调用Fragment的自定义方法resetFragmentData(),把旧数据替换掉。注:resetFragmentData只能做数据替换,不能直接更新view,View的更新还是在调用attach方法后继续执行到onActivityCreated方法后执行刷新View。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
publicclass CarTypeListAdapter extendsFragmentPagerAdapter {
 
    privatefinal ArrayList<CarTypeListMinPriceResult.CarTypeMinPrice> mRecList;
    protectedImageWorker mImageFetcher;
 
    publicCarTypeListAdapter(FragmentManager fm, ArrayList<CarTypeListMinPriceResult.CarTypeMinPrice> recList, ImageWorker worker) {
        super(fm);
        this.mRecList = recList;
        this.mImageFetcher = worker;
    }
 
    @Override
    publicFragment getItem(intposition) {
        CarTypeInfoFragment imageFragment = CarTypeInfoFragment.newInstance(mRecList.get(position), mImageFetcher);
        returnimageFragment;
    }
 
    publicObject instantiateItem(ViewGroup container, intposition) {
        CarTypeInfoFragment f = (CarTypeInfoFragment)super.instantiateItem(container, position);
        if(!QArrays.isEmpty(mRecList) && position >=0&& position < mRecList.size()){
            CarTypeListMinPriceResult.CarTypeMinPrice p = mRecList.get(position);
            if(p != null){
                f.resetFragmentData(p);
            }
        }
 
        returnf;
    }
 
    @Override
     publicint getItemPosition(Object object) {
        returnPOSITION_NONE;
    }
 
    @Override
    publicint getCount() {
        returnmRecList == null? 0: mRecList.size();
    }
}

相关文章推荐

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动。不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,...

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

文章转自http://www.apkbus.com/android-90417-1-1.html

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动。不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,我希...

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动。不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,...

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

刚好做项目的时候遇到这个问题,看到一篇文章分析的很全面. 原文地址:http://www.cnblogs.com/dancefire/archive/2013/01/02/why-notifyDat...

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动。不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,...

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动。不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,...

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

原文地址http://blog.csdn.net/w250shini11/article/details/8538560

为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?

在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动。不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)