使用兼容包以使用片段的2.2为目标。
在重新编写活动以使用应用程序中的片段后,我无法使方向更改/状态管理正常工作,因此我创建了一个具有单个FragmentActivity和单个片段的小型测试应用程序。
来自方向更改的日志很奇怪,有多个对片段OnCreateView的调用。
我显然遗漏了一些东西--比如分离片段并重新附加它,而不是创建一个新的实例,但是我看不到任何文档可以指出我哪里出错了。
有没有人能解释一下我做错了什么。谢谢
方向更改后的日志如下所示。
Initial creation
12-04 11:57:15.808: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:15.945: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:16.081: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Orientation Change 1
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:57:39.031: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.167: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
Orientation Change 2
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.361: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null
主要活动(FragmentActivity)
public class FragmentTestActivity extends FragmentActivity {
/** Called when the activity is first created. */
private static final String TAG = "FragmentTest.FragmentTestActivity";
FragmentManager mFragmentManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(TAG, "onCreate");
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}
和片断
public class FragmentOne extends Fragment {
private static final String TAG = "FragmentTest.FragmentOne";
EditText mEditText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "OnCreateView");
View v = inflater.inflate(R.layout.fragmentonelayout, container, false);
// Retrieve the text editor, and restore the last saved state if needed.
mEditText = (EditText)v.findViewById(R.id.editText1);
if (savedInstanceState != null) {
Log.d(TAG, "OnCreateView->SavedInstanceState not null");
mEditText.setText(savedInstanceState.getCharSequence("text"));
}
else {
Log.d(TAG,"OnCreateView->SavedInstanceState null");
}
return v;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.d(TAG, "FragmentOne.onSaveInstanceState");
// Remember the current text, to restore if we later restart.
outState.putCharSequence("text", mEditText.getText());
}
清单
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".activities.FragmentTestActivity"
android:configChanges="orientation">
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
发布于 2011-12-30 18:57:04
你将你的碎片层叠在另一个之上。
当配置发生更改时,旧片段会在重新创建时将其自身添加到新活动中。这是一个巨大的疼痛,在大部分时间在后方。
您可以使用相同的片段来停止错误的发生,而不是重新创建新的片段。只需添加以下代码:
if (savedInstanceState == null) {
// only create fragment if activity is started for the first time
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} else {
// do nothing - fragment is recreated automatically
}
不过要注意:如果您尝试从片段内部访问活动视图,将会出现问题,因为生命周期将发生微妙的变化。(从片段中获取父活动的视图并不容易)。
发布于 2013-06-06 02:05:03
引用this book的话说,“为了确保一致的用户体验,当活动由于配置改变而重启时,Android会保留片段布局和相关的后台堆栈。”(第124页)
实现这一点的方法是首先检查片段后堆栈是否已经填充,只有在还没有填充的时候才创建新的片段实例:
@Override
public void onCreate(Bundle savedInstanceState) {
...
FragmentOne fragment = (FragmentOne) mFragmentManager.findFragmentById(R.id.fragment_container);
if (fragment == null) {
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.fragment_container, new FragmentOne());
fragmentTransaction.commit();
}
}
发布于 2013-09-10 21:57:17
正如您所看到的,您的活动的onCreate()方法在方向更改之后被调用。因此,不要在您的活动中执行在方向更改之后添加片段的FragmentTransaction。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState==null) {
//do your stuff
}
}
片段应该并且必须保持不变。
https://stackoverflow.com/questions/8474104
复制相似问题