我正面临一个令我疯狂的问题。我有一个基于NavigationStudio设置的NavigationDrawer的应用程序。
我的MainActivity类有这个方法,我在其中实例化片段:
@Override
public void onNavigationDrawerItemSelected(int position) {
Log.i(this.toString(), "onNavigationDrawerItemSelected() -> Instance new Fragment");
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment;
switch (position) {
case 0:
fragment = new MapFragment();
break;
case 1:
fragment = new SettingsFragment();
break;
default:
fragment = new MapFragment();
break;
}
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
我的MapFragment覆盖了这种数据恢复方法:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.i(this.toString(), "onActivityCreated savedInstanceState -> " + (savedInstanceState == null ? "NULL" : "DATA"));
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
// TODO: Restore markers, polylines, etc
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
Log.i(this.toString(), "onSaveInstanceState()");
// Saves the data
outState.putParcelableArray("lineas", mLineas);
super.onSaveInstanceState(outState);
}
问题是,当我旋转设备时,系统正在调用两次。第一次,onActivityCreated接收到包OK,但第二次,它为null,导致Fragment实例没有恢复的数据。这是我的logcat:
02-12 19:19:34.866 11270-11270/com.pinard.bustracer I/MapFragment{4285f5a0 #1 id=0x7f080040}﹕ onSaveInstanceState()
02-12 19:19:34.947 11270-11270/com.pinard.bustracer I/MapFragment{4285f5a0 #1 id=0x7f080040}﹕ onDetach()
02-12 19:19:35.047 11270-11270/com.pinard.bustracer I/com.pinard.bustracer.MainActivity@42be59a0﹕ onCreate savedInstanceState -> DATA
02-12 19:19:35.047 11270-11270/com.pinard.bustracer I/MapFragment{42be7448 #1 id=0x7f080040}﹕ onAttach()
02-12 19:19:35.047 11270-11270/com.pinard.bustracer I/MapFragment{42be7448 #1 id=0x7f080040}﹕ onCreate savedInstanceState -> DATA
02-12 19:19:35.067 11270-11270/com.pinard.bustracer I/com.pinard.bustracer.MainActivity@42be59a0﹕ onNavigationDrawerItemSelected() -> Instance new Fragment
02-12 19:19:35.087 11270-11270/com.pinard.bustracer I/MapFragment{42be7448 #1 id=0x7f080040}﹕ onCreateView savedInstanceState -> DATA
02-12 19:19:35.127 11270-11270/com.pinard.bustracer I/MapFragment{42be7448 #1 id=0x7f080040}﹕ onActivityCreated savedInstanceState -> DATA
02-12 19:19:35.147 11270-11270/com.pinard.bustracer I/MapFragment{42be7448 #1 id=0x7f080040}﹕ onDetach()
02-12 19:19:35.147 11270-11270/com.pinard.bustracer I/MapFragment{42c570b8 #1 id=0x7f080040}﹕ onAttach()
02-12 19:19:35.147 11270-11270/com.pinard.bustracer I/MapFragment{42c570b8 #1 id=0x7f080040}﹕ onCreate savedInstanceState -> NULL
02-12 19:19:35.147 11270-11270/com.pinard.bustracer I/MapFragment{42c570b8 #1 id=0x7f080040}﹕ onCreateView savedInstanceState -> NULL
02-12 19:19:35.157 11270-11270/com.pinard.bustracer I/MapFragment{42c570b8 #1 id=0x7f080040}﹕ onActivityCreated savedInstanceState -> NULL
02-12 19:19:35.157 11270-11270/com.pinard.bustracer I/MapFragment{42c570b8 #1 id=0x7f080040}﹕ onStart()
02-12 19:19:35.757 11270-11270/com.pinard.bustracer I/MapFragment{42c570b8 #1 id=0x7f080040}﹕ onResume()
我在SO中已经阅读了很多内容,但无法找到解决方案。
我错过了什么?你能指点我的方向吗?
答案 0 :(得分:2)
Bundle
为空的原因是因为您正在创建new
MapFragment
。请注意,在您的日志中,第一个MapFragment
位于42be7448
,第二个位于42c570b8
。
要保持实例状态捆绑,您需要保留MapFragment
实例。考虑一下这个
// Class level
private MapFragment mMapFragment;
private SettingsFragment mSettingsFragment;
Fragment fragment;
switch (position) {
case 0:
fragment = mMapFragment == null ? new MapFragment() : mMapFragment;
break;
case 1:
fragment = mSettingsFragment == null ? new SettingsFragment() : mSettingsFragment;
break;
default:
fragment = mMapFragment == null ? new MapFragment() : mMapFragment;
break;
}
这会缓存你的碎片并允许状态继续进行。
我还认为您的Activity重新创建自身存在问题。设置回调时会调用onNavigationDrawerItemSelected
,所以你看到的是。
1)你的碎片被破坏了。
2)你的活动被破坏了。
3)您的活动会被重新创建。
4)您的Fragment创建了一个新实例。 < - 这就是你需要停止的。
答案 1 :(得分:2)
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
string s;
if(position == 0)
{
s = MapFragment.Tag;
}
else
{
s = SettingsFragment.TAg;
}
Fragment fragment;
fargment = fragmentManager.findFragmentByTag(s);
if(null == fragment)
{
string tag = null;
switch (position) {
case 0:
fragment = new MapFragment();
tag = MapFragment.Tag;
break;
case 1:
fragment = new SettingsFragment();
tag = SettingsFragment.Tag;
break;
default:
fragment = new MapFragment();
tag = MapFragment.Tag;
break;
}
}
fragmentManager.beginTransaction()
.replace(R.id.container, fragment, tag)
.commit();
// THe code is not optimised by gives u idea what u need to do. the tags are static methods that u need to add to ur settings and map fragment