我有我的ViewPager
和OffscreenPageLimit=2
(容易重現我的錯誤)6頁。
6頁中的所有數據都來自服務器。在onCreateView
中,我向服務器發送請求,並在從服務器獲取數據時刷新UI。片段創建/恢復重複的數據視圖時重新連接
當我選擇第一個選項卡並更改持續快速幾次,一些尋呼機顯示錯誤。而在那個時候,我的字段mMainLayout
在片段中不爲空。
例如,我在第一頁有ListView
。當頁面出錯時,另一個ListView位於右側頂部ListView。當我嘗試滾動ListView時,只有正確的一個(底部)移動。
我知道,我的回答聽衆持有mMainLayout和其他一些意見的參考,我在方法onCreateView創建一個新的mMainLayout,我以爲片段使用新mMainLayout當它重新連接/恢復和放下舊的(或從容器中取出)。但是我錯了。
我知道FragmentPagerAdapter
在instantiateItem
上附加/重新附加片段,並在destroyItem
中分離。適配器沒有刪除一個片段。適配器沒有創建新的片段。片段保持視圖和視圖狀態本身。
我從容器中取出mMainLayout和onDestroyView
設置在我的片段空所有的意見,並保存在沒有onSaveInstanceState
。但仍然容易重現該錯誤。
活動:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
registerReceiver(receiver, new IntentFilter("com.souyidai.intent.action.log_fragment"));
FragmentManager fragmentManager = getFragmentManager();
mResources = getResources();
mMainPagerAdapter = new MainPagerAdapter(fragmentManager);
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mMainPagerAdapter);
mPager.setOffscreenPageLimit(CACHE_SIZE);
mIndicator = (TabPageIndicator) findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
...
}
private class MainPagerAdapter extends FragmentPagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
MainConfig.TabItem tab = mTabs.get(position);
String tabType = tab.getTabType();
String code = tab.getCode();
MainConfig.TabItem.SubTabItem subTabItem = tab.getSubitem().get(0);
Fragment fragment = MainFragment.newInstance(code, subTabItem);
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
MainConfig.TabItem tab = mTabs.get(position);
return tab.getTitle();
}
@Override
public int getCount() {
return mTabs.size();
}
}
片段:
android.support.v13.app.FragmentPagerAdapter
@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) {
FragmentCompat.setMenuVisibility(fragment, false);
FragmentCompat.setUserVisibleHint(fragment, false);
}
return fragment;
}
我發現這一點:
Android fragment onCreateView creating duplicate views on top of each other
但我只在FragmentPagerAdapter.getItem
創造新的片段。所以我們不同。
我通過去除所有兒童mMainLayout如果mMainLayout不是方法onCreateView空解決這個問題。然後一切都很好。但我仍然對這個錯誤發生的原因感到困惑。
我做了一些測試。
1.嘗試添加一個片段兩次,應用程序崩潰和日誌說:java.lang.IllegalStateException:已添加片段:...
2。嘗試附加片段的兩倍,系統不叫Fragment.onCreate
或Fragment.onCreateView
請加你的代碼 –
使用'setRetainInstance(true)'片段的api如果你想保留你的片段狀態。 在第二次加載同一個片段時,如果它是在內存中,它將從之前的實例加載UI組件,否則將創建新的片段。 因此,您不需要在ondestroyview方法中使所有UI組件空。 –
@ keyur9779我不想保留我的片段狀態。但它看起來像片段仍然從以前恢復狀態。 –