Android填坑之路——FragmentPagerAdapter无法更新数据

原因分析

在使用ViewPager+FragmentPagerAdapter时候,更新Fragment里数据是不起作用,FragmentPagerAdapter添加Fragment、减少Fragment、切换顺序时,前面的Fragment内容更新不起作用。这是因为
FragmentPagerAdapter的创建fragment机制所导致的。定位到FragmentPagerAdapter源码,其中创建更新fragment的方法是instantiateItem:

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        if (fragment != mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false);
            fragment.setUserVisibleHint(false);
        }

        return fragment;
    }

instantiateItem方法中会根据itemId生成name来查找fragment是否已经存在,如果不存在则创建新的fragment,否则不创建新的fragment。
itemId是通过getItemId方法获取的,那么,定位到getItemId方法:

public long getItemId(int position) {
        return position;
    }

getItemId仅仅只是返回当前的position。这就是FragmentPagerAdapter无法更新的原因了。比如FragmentPagerAdapter有3个fragment, 那么通过getItemId获取到的itemId就为0, 1, 2,这时变更数据,把第一个fragment的数据与第三个fragment交换,但getItemId获取到的itemId仍是0, 1, 2,instantiateItem方法里就不会去执行新的创建或更新数据了。这就是FragmentPagerAdapter无法更新数据的原因了。

解决方案

1、暴力移除fragment

ist<Fragment> fragments = getSupportFragmentManager().getFragments();
for (int i = fragments.size() - 1; i >= 0; i--) {
    getSupportFragmentManager().beginTransaction().remove(fragments.get(0));
}

2、重写instantiateItem方法

3、重写getItemId方法

@Override
public long getItemId(int position) {
    // 获取当前数据的hashCode
    int hashCode = data.get(position).hashCode();
    return hashCode;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容