Android填坑之路——FragmentPagerAdapter無法更新數(shù)據(jù)

原因分析

在使用ViewPager+FragmentPagerAdapter時候,更新Fragment里數(shù)據(jù)是不起作用,F(xiàn)ragmentPagerAdapter添加Fragment、減少Fragment、切換順序時,前面的Fragment內(nèi)容更新不起作用。這是因為
FragmentPagerAdapter的創(chuàng)建fragment機制所導致的。定位到FragmentPagerAdapter源碼,其中創(chuàng)建更新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方法中會根據(jù)itemId生成name來查找fragment是否已經(jīng)存在,如果不存在則創(chuàng)建新的fragment,否則不創(chuàng)建新的fragment。
itemId是通過getItemId方法獲取的,那么,定位到getItemId方法:

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

getItemId僅僅只是返回當前的position。這就是FragmentPagerAdapter無法更新的原因了。比如FragmentPagerAdapter有3個fragment, 那么通過getItemId獲取到的itemId就為0, 1, 2,這時變更數(shù)據(jù),把第一個fragment的數(shù)據(jù)與第三個fragment交換,但getItemId獲取到的itemId仍是0, 1, 2,instantiateItem方法里就不會去執(zhí)行新的創(chuàng)建或更新數(shù)據(jù)了。這就是FragmentPagerAdapter無法更新數(shù)據(jù)的原因了。

解決方案

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) {
    // 獲取當前數(shù)據(jù)的hashCode
    int hashCode = data.get(position).hashCode();
    return hashCode;
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容