【问题标题】:Dynamic Fragments and screen rotation动态片段和屏幕旋转
【发布时间】:2014-01-30 09:08:36
【问题描述】:

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

我有什么

具有三个通过 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: Can't change container ID of Fragment )。

问题出在这里:

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 部分。出于某种原因,“它”不喜欢检索已经创建的片段的想法。有趣的是,当我摆脱 else 并且只保留上半部分时,一切正常。出于某种原因,它在我创建新片段时有效,但在我要求它重用旧片段时无效。

问题

谁能解释为什么它不允许我重用已经创建的片段?

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

我们将不胜感激有关重用片段的一些宏观想法。

对于这么长的帖子,我深表歉意。

【问题讨论】:

    标签: android performance android-fragments


    【解决方案1】:

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

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

    这家伙解释得很好。

    希望这会有所帮助!

    【讨论】:

    • 感谢您的链接。我确实使用 findByTag 重新获取对已创建片段的引用。但是由于某种原因它仍然无法正常工作......
    猜你喜欢
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    相关资源
    最近更新 更多