我有一个以编程方式添加的片段。然而,我发现在旋转之后,会创建一个新片段,但旧片段仍处于活动状态(虽然没有显示)我假设片段与旋转活动一起被销毁,但这不是这里的情况。什么可能导致我的片段被保留/不被破坏? 请注意:
创建片段的代码:
MyFragment fragment = MyFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment");
fragmentTransaction.show(fragment).commit();
删除片段的代码:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment).commit();
更新: 我无法确认这是否是问题,但片段在onCreate中注册为LocalBroadcast接收器。它在onDestroy中未注册广播,但似乎LocalBroadcast注册阻止调用onDestroy,或者在旋转时没有调用onDestroy。我现在在onStop中取消注册,这似乎解决了这个问题。
答案 0 :(得分:15)
当由于方向更改而重新启动Activity时,Android Framework会自动为您重新创建并添加Fragment。
您可能会在onCreate
的{{1}}中添加片段。这是您在方向更改后添加其他片段的位置。
您必须检查是否已添加片段:
Activity
每次添加添加片段的按钮时,都会添加一个新的片段。如果您的容器是FrameLayout,您可能不会看到它。尝试替换碎片:
Fragment f = getFragmentManager().findFragmentById(R.id.content_frame);
if(f == null){
//Add it, there is no Fragment
}else{
//It's already there
}
方法fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment");
有另一个目的。如果启用它,则方向更改时将不会销毁setRetainInstance(true)
实例(但其视图将被销毁)。这意味着您可以将数据存储在Fragment
的成员变量中,并且这些数据在方向更改后仍然可用。
设置Fragment
时片段的生命周期略有不同。即setRetainInstance(true)
和onCreate()
未被调用(因为这些事件不会发生)
答案 1 :(得分:2)
为什么不能用要加载的新片段替换现有片段。
试试这可能对你有帮助。
FragmentNew mFragmentNew = new FragmentNew ();// Which you want to load That Fragment Object
getFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, mFragmentNew)
.commit();
答案 2 :(得分:2)
你的片段可能在活动onDestroy()之前保存在Bundle对象中。尝试在onSaveInstanceState()中处理删除片段:
@Override
protected void onSaveInstanceState(Bundle outState) {
//remove here fragments
super.onSaveInstanceState(outState);
}
或者你可以在onCreate()中使Bundle为null:
@Override
protected void onCreate(Bundle savedInstanceState) {
savedInstanceState = null;
super.onCreate(savedInstanceState);
}
答案 3 :(得分:1)
我遇到了这个问题,我解决了这个问题,只需更换此行
fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment");
要
fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment");
享受
答案 4 :(得分:0)
首次启动时只需添加Fragment
一次,就像这样:
以下代码是从http://developer.android.com/reference/android/app/Fragment.html复制的,评论是我的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// My Comment: only add when launched for the first time, it won't be null on orientation change
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}