简体   繁体   English

布局更改时的片段管理

[英]Fragment management when the layout changes

I have an application with a single Activity and two fragments. 我有一个带有单个活动和两个片段的应用程序。 The desired behavior is (user interaction highlighted in blue color): 所需的行为是(用户交互以蓝色突出显示):

In portrait 在肖像中

在此处输入图片说明

In landscape 在风景中

在此处输入图片说明

My current solution is: 我当前的解决方案是:

Layout in landscape 景观布局

FrameLayout
   ContainerRed(FrameLayout)
   ContainerYellow(FrameLayout)

Layout in portrait 纵向布局

LinearLayout
   ContainerRed(FrameLayout weight=1)
   ContainerYellow(FrameLayout weight=1)

When the user clicks the green button I do the following transactions: 当用户单击绿色按钮时,我进行以下交易:

  • In portrait: Remove FragmentA, add FragmentB to containerYellow, addToBackstack 在肖像中:删除FragmentA,将FragmentB添加到containerYellow,添加至Backstack
  • In landscape: add FragmentB to contanerYellow, addToBackstack 在横向中:将FragmentB添加到contanerYellow,然后添加到Backstack

This implements a correct behaviour except if you rotate the device after a transaction, for example, if you are in portrait, go to the screen B1 and then rotate the device to landscape the FragmentA slot is empty. 这实现了正确的行为,除非您在事务处理后旋转设备(例如,如果您是纵向的),请转到屏幕B1,然后旋转设备以使其横向运行,FragmentA插槽为空。

Additionally if you are in the screen B2 and rotate the screen to portrait the FragmentA appears in the background of the FragmentB. 另外,如果您在屏幕B2中并旋转屏幕以使其纵向,则FragmentA会出现在FragmentB的背景中。

How can I solve that? 我该如何解决? thanks 谢谢

I have a solution that works: 我有一个可行的解决方案:

First use the same tag for the addToBackstack("FOO"); 首先对addToBackstack(“ FOO”)使用相同的标签;

In at the end of the onCreate method of the Activity call: 在Activity调用的onCreate方法末尾:

Fragment fragmentB=getFragmentManager().findFragmentByTag("FRAGMENT_B_TAG");
if (fragmentB!=null){
   getFragmentManager().popBackStackImmediate("FOO",
                FragmentManager.POP_BACK_STACK_INCLUSIVE);
   attachFragmentB(fragmentB);
}

void attachFragmentB(Fragment fragmentB){
  //In portrait: Remove FragmentA, add FragmentB to containerYellow, addToBackstack("FOO")
  //In landscape: add FragmentB to contanerYellow, addToBackstack("FOO")
}

An other way of doing this without multiple layouts and backstack tricks is to modify the visibility of your containers both in onCreate() and in onBackStackChanged(). 没有多种布局和后退技巧的另一种方法是在onCreate()和onBackStackChanged()中修改容器的可见性。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            if (getSupportFragmentManager().findFragmentByTag(AFragment.TAG) == null) {
                Fragment fragment = new AFragment();
                getSupportFragmentManager()
                        .beginTransaction()
                        .replace(R.id.layout_left, fragment,AFragment.TAG)
                        .commit();
            }
        }
        getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
            @Override
            public void   onBackStackChanged() {
                updateScreen();
            }
        });
        updateScreen();
    }

    //called when A button's is clicked
    public void onClick() {
        if (getSupportFragmentManager().findFragmentByTag(BFragment.TAG) == null) {
            Fragment fragment = new BFragment();
            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.layout_right, fragment, BFragment.TAG)
                    .addToBackStack(BFragment.TAG)
                    .commit();
        }
    }

    public void updateScreen(){
        if (getSupportFragmentManager().findFragmentByTag(BFragment.TAG) != null){
            if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                findViewById(R.id.layout_right).setVisibility(View.VISIBLE);
                findViewById(R.id.layout_left).setVisibility(View.VISIBLE);
            }else{
                findViewById(R.id.layout_right).setVisibility(View.VISIBLE);
                findViewById(R.id.layout_left).setVisibility(View.GONE);
            }
        }else{
            findViewById(R.id.layout_right).setVisibility(View.GONE);
            findViewById(R.id.layout_left).setVisibility(View.VISIBLE);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM