我有我的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我不想保留我的片段状态。但它看起来像片段仍然从以前恢复状态。 –