and*_*_su 6 android fragment android-fragments android-viewpager
我在6页ViewPager
和OffscreenPageLimit=2
(容易重现我的错误).
6页中的所有数据均来自服务器.在onCreateView
,我向服务器发送请求,并在从服务器获取数据时刷新UI.
当我选择第一个选项卡并快速更改为最后一次时,某些寻呼机显示错误.那时我mMainLayout
的片段中的字段不为空.
例如,ListView
我的第一页有一个.当页面错误时,另一个ListView位于右侧ListView的顶部.当我尝试滚动ListView时,只移动了正确的一个(底部一个).
我知道我的响应监听器持有mMainLayout和其他一些视图的参考,我在方法onCreateView中创建了一个新的mMainLayout,我认为片段在重新连接/恢复时使用新的mMainLayout并丢弃旧的(或从容器中删除) .但是我错了.
我知道FragmentPagerAdapter
附加/重新附加片段instantiateItem
和分离destroyItem
.适配器没有删除片段.适配器没有制作新片段.片段保持视图并查看状态本身.
我从容器中删除mMainLayout并将我的片段中的所有视图设置为null onDestroyView
并且不保存任何内容onSaveInstanceState
.但仍然很容易重现这个bug.
活动:
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
分段:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContainer = container;
mMainLayout = inflater.inflate(R.layout.fragment_main, container, false);
...
}
@Override
public void onDestroyView() {
super.onDestroyView();
mContainer.removeView(mMainLayout);
mContainer = null;
mMainLayout = null;
mSwipeRefreshLayout = null;
mListView = null;
mHeaderLayout = null;
mFooterLayout = null;
...
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
我发现这个:
Android片段onCreateView在彼此之上创建重复的视图
但我只创建了新片段FragmentPagerAdapter.getItem
.所以我们是不同的.
我通过删除mMainLayout的所有子节点来解决这个问题,如果在方法onCreateView中mMainLayout不为null .一切都很好.但我仍然对这个错误发生的原因感到困惑?
我做了一些测试.
1.尝试添加一个片段两次,app崩溃和日志说:java.lang.IllegalStateException:已添加片段:...
2.尝试连接片段两次,系统不调用Fragment.onCreate
或Fragment.onCreateView
这种情况的发生是由于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);
//make sure you are not attaching already added fragment
//try with comment and uncomment two lines below
//if(!fragment.isAdded())
//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;
}
Run Code Online (Sandbox Code Playgroud)
不知道为什么你要创建类成员字段mMainLayout
//try to go with default
View view = inflater.inflate(R.layout.fragment_main, container, false);
Run Code Online (Sandbox Code Playgroud)
推荐你学习这个
归档时间: |
|
查看次数: |
836 次 |
最近记录: |