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 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;
}

你可能感兴趣的:(Android填坑之路——FragmentPagerAdapter无法更新数据)