2

I have an application with a single Activity and two fragments. The desired behavior is (user interaction highlighted in blue color):

In portrait

enter image description here

In landscape

enter image description here

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
  • In landscape: add FragmentB to contanerYellow, addToBackstack

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.

Additionally if you are in the screen B2 and rotate the screen to portrait the FragmentA appears in the background of the FragmentB.

How can I solve that? thanks

Addev
  • 31,819
  • 51
  • 183
  • 302

2 Answers2

2

I have a solution that works:

First use the same tag for the addToBackstack("FOO");

In at the end of the onCreate method of the Activity call:

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")
}
Addev
  • 31,819
  • 51
  • 183
  • 302
  • oh I get it, you're using a tag to keep track of the activity stack then? Does this code go into the onCreate of FragmentA? – reidisaki Jul 02 '14 at 17:02
  • No, it goes in the onCreate of the Activity that contains both fragments. Basically with this code, you revert the fragment transaction you did in the other orientation and re-do it acording to the new orientation – Addev Jul 02 '14 at 17:03
1

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().

    @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);
        }
    }
user2641570
  • 804
  • 8
  • 20