动态片段和屏幕旋转

时间:2014-01-30 09:08:37

标签: android performance android-fragments

我已经搜索过这个问题了,似乎还没有提出这样的问题。

我有什么

一个应用程序,它有三个通过java代码添加的片段(没有<frgament> </fragment>)。当设备处于横向模式时,所有三个片段一起显示。另一方面,在纵向模式下,仅显示一个。以纵向模式显示的片段有一个按钮。如果按下该按钮,则会触发一个事件,通知监听器(在我的情况下为主要活动),然后将该片段替换为另一个片段。一切都发生在一项活动中。

以下是来自活动的onCreate():

protected void onCreate(Bundle savedInstanceState){          super.onCreate(savedInstanceState);

     //depending on the orientation this layout file is different. 
     setContentView(R.layout.fragment_layout);

     //landscapeCase
     if (getResources().getConfiguration().orientation
             == Configuration.ORIENTATION_LANDSCAPE) {


         //adding three fragments into their places

         FragmentManager fragMgr = getFragmentManager();


         FragmentTransaction xact = fragMgr.beginTransaction();

         if(fragMgr.findFragmentByTag(FRAG1_TAG)==null){

             xact.add(R.id.frame1,new AddNoteFragment(), FRAG1_TAG );
         }

         if(fragMgr.findFragmentByTag(FRAG2_TAG)==null){

             xact.add(R.id.frame2,new ListNoteFragment(), FRAG2_TAG );

         }

         if(fragMgr.findFragmentByTag(FRAG3_TAG)==null){
             xact.add(R.id.frame3,new DetailNoteFragment(), FRAG3_TAG );

         }


         xact.commit(); 

     }

     //portrait case
     if (savedInstanceState == null) {


         FragmentManager fragMgr = getFragmentManager();


         FragmentTransaction xact = fragMgr.beginTransaction();

         if(fragMgr.findFragmentByTag(FRAG1_TAG)==null){
             xact.add(R.id.frame1,new AddNoteFragment(), FRAG1_TAG );   
         }
         xact.commit();

     }
 }

这是OnPressed方法,用于处理纵向情况下片段中的按钮按下:

   //frame1, frame2 and frame3 are the layouts inside (fragment_layout.xml) that are dedicated to the              //fragments.
   //in portrait mode only frame1 is available.
    @Override
        public void OnPressed(String TAG) {
            if(TAG.equals("frag1") && getResources().getConfiguration().orientation
                    == Configuration.ORIENTATION_PORTRAIT){



            FragmentManager fragMgr = getFragmentManager();  
             FragmentTransaction xact = fragMgr.beginTransaction();

            if(fragMgr.findFragmentByTag(FRAG2_TAG)==null) {

                xact.replace(R.id.frame1, new ListNoteFragment(), FRAG2_TAG);
                 }

            else {
                //problem occurs here.
                xact.replace(R.id.frame1, fragMgr.findFragmentByTag(FRAG2_TAG));

                }
            xact.addToBackStack(null);
            xact.commit();

            }

            }

问题

严格以纵向模式更换碎片的过程(包括后退按钮)。但是,如果我切换到横向然后回到纵向然后按下按钮,一切都会崩溃(IllegalStateException:无法更改Fragment的容器ID)。

问题源于此:

if(fragMgr.findFragmentByTag(FRAG2_TAG)==null) {

                xact.replace(R.id.frame1, new ListNoteFragment(), FRAG2_TAG);
                 }

            else {
                //problem occurs here.
                xact.replace(R.id.frame1, fragMgr.findFragmentByTag(FRAG2_TAG));

                }

旋转发生后,会创建FRAG2_TAG片段,因此当返回纵向案例并按下按钮时,会执行else部分。出于某种原因,“它”不喜欢检索已经创建的片段的想法。有趣的是,当我摆脱其他而只保持上半部分一切正常。出于某种原因,它在我创建新片段时起作用,但在我要求它重用旧片段时却不起作用。

问题

任何人都可以解释为什么它不允许我重复使用已创建的片段吗?

是否可以只创建三个片段,以便它们可以横向模式一起显示,并在纵向之间切换(所有单个活动)?

关于重复使用片段的一些重要想法将非常受欢迎。

我为这么长的帖子道歉。

1 个答案:

答案 0 :(得分:1)

您可以重复使用已创建的片段。它崩溃的原因是因为片段会尝试重新创建自己。您必须检查片段是否已存在。以下是您的问题的解决方案:

https://stackoverflow.com/a/9646622/2767703

这家伙完美地解释了它。

希望这有帮助!