2013-02-25 52 views
4

我对此非常困惑。我有一个actionbar列表导航。我点击列表一个接一个地打开2 fragment并显示在同一活动中。我使用这种方法基本上替换它们:片段在活动轮转上重叠

public void openFragment(AprilAppsFragment createdFragment){   
    if (createdFragment.getClass().isInstance(getDisplayedFragment())) 
     return; 

    FragmentManager manager = getSupportFragmentManager(); 
    FragmentTransaction transaction = manager.beginTransaction(); 
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 

    transaction.replace(R.id.main_fragment, createdFragment, "displayed fragment"); 
    transaction.addToBackStack(null); 
    transaction.commit(); 
} 

我打开片段,然后我打开片段,然后我旋转屏幕。片段A正在重新创建崩溃我的应用程序

因为我使用替换?我如何避免重新创建不再显示的碎片,而不会丢失对它们进行反压的可能性?

+0

你可以从崩溃中添加堆栈跟踪? – ianhanniballake 2013-02-25 19:19:04

+0

这将是无关紧要的。崩溃发生时,片段试图用数据填充其内容,但无法实例化视图组件,因为它甚至未显示 – 2013-02-25 19:20:12

+0

您是否从“OnNavigationListener”调用该方法?如果是,请记住,活动创建/娱乐会触发侦听器。 – Luksprog 2013-03-01 14:05:10

回答

9

你的问题是,你不节能状态的碎片,因为你还没有加入

android:configChanges="orientation|screenSize" 

你的第一个片段再次呼吁,既然你有没有保存状态你的应用程序崩溃。所以它的好,你添加行上面,你的活动申报清单,如:

<activity android:name=".yourActivity" android:configChanges="orientation|screenSize" 

并覆盖和的onSaveInstanceState保存状态为您的片段。而在你的onCreate只是做此项检查:

if(savedInstanceState != null){ 
fragmentA = (FragmentA) fragmentManager.getFragment(savedInstanceState, stringValueA); 
fragmentB = (FragmentB) fragmentManager.getFragment(savedInstanceState, stringValueB); 
} 

,然后检查你的任何片段不为空不是创建它的实例,并将其设置为fragmentTransaction.relplace。或者在你的openFragment方法中做到这一点。

干杯,

+1

它并没有真正回答为什么娱乐活动重新创建所有片段,甚至是被替换的片段。 configChanges实际上停止了娱乐活动,但它不能与ActionBarSherlock一起工作,我只能在ICS后期系统上尝试 – 2013-03-10 09:41:37

+0

阅读本主题中的答案:http://stackoverflow.com/questions/14184182/why-wont-fragment-retain - 状态 - 当屏幕旋转 – AliR 2013-03-11 00:12:11

+0

完美!!!!!!!!!!!!!!!!!!!! – 2014-01-07 04:52:03

2

碎片自动保存它们的状态(以及背堆栈上的位置)。确保你没有重新创建你的片段,或者在onActivityCreated或onCreate方法中调用openFragment。

+0

我不是,我敢肯定 – 2013-02-25 19:18:05

+0

因此,您创建片段A和片段B(即调用此openFragment方法)的唯一位置是列表中的单击方法吗? – ianhanniballake 2013-02-25 19:28:07

+0

究竟,这是唯一的地方 – 2013-02-25 19:30:22

1

我有一个类似的问题,我做的是在我的 AndroidManifest.xml中添加代码行(你的活动,美要停止重建内线):

机器人:configChanges =“方向”

还有一件事,我才知道,片段是一种子活动和不活动, 我们一定要为获得与片段支持延伸的活动片段,并且extands活动活动片段是持有“子活动”的实际活动那叫做碎片。

我希望我帮助ü...

1

添加到您的活动定义在AndroidManifest.xml档案:

android:configChanges="keyboardHidden|screenLayout|orientation|screenSize" 

这将保持活动从自动重新创建重启和FragmentManager它具有的片段。

如果您需要在循环中重新启动活动,那么您必须查找正在传递给onCreate的savedInstanceState,然后使用您提供的标记来查询FragmentManager。

2

您的问题是您的活动正在重新创建,这会导致您重新设置列表导航,导致默认(第一个)位置被触发。您需要在活动销毁和活动重新消费之间保存选定的索引。这里有一个例子:

@Override 
public void onCreate(Bundle savedInstanceState) { 

    // onCreate implementation... 

    // Must come after setListNavigationCallbacks is called 
    if (savedInstanceState != null) { 
     int index = savedInstanceState.getInt("index"); 
     getActionBar().setSelectedNavigationItem(index); 
    } 
} 

@Override 
protected void onSaveInstanceState(Bundle outState) { 

    super.onSaveInstanceState(outState); 
    outState.putInt("index", getActionBar().getSelectedNavigationIndex()); 
} 
+0

为什么downvote?我的答案是什么没有用? – 2013-03-11 07:20:57