How to replace fragment C with fragment A when back button is pressed?

后端 未结 3 1545
独厮守ぢ
独厮守ぢ 2021-01-30 11:02

My scenario : Activity 1 consists of Fragments A-> B-> C. All the fragments are added using this code :

        FragmentManager fm = getSupportFragmentManager()         


        
相关标签:
3条回答
  • 2021-01-30 11:22

    You need to do 2 things - name the FragmentTransaction from A->B and then override onBackPressed() in your containing activity to call FragmentManager#popBackStack (String name, int flags) when you are on Fragment C. Example:

    Transition from A->B

    getSupportFragmentManager()
      .beginTransaction()
      .replace(R.id.container, new FragmentB(), "FragmentB")
      .addToBackStack("A_B_TAG")
      .commit();
    

    Transition from B->C will use a similar transaction with "FragmentC" as its tag.

    Then in your containing Activity override onBackPressed():

    @Override
    public void onBackPressed() {
      if (getSupportFragmentManager().findFragmentByTag("FragmentC") != null) {
        // I'm viewing Fragment C
        getSupportFragmentManager().popBackStack("A_B_TAG",
          FragmentManager.POP_BACK_STACK_INCLUSIVE);
      } else {
        super.onBackPressed();
      }
    }
    
    0 讨论(0)
  • 2021-01-30 11:26

    Theory

    Use the addToBackStack(tag: String): FragmentTransaction method from within the FragmentTransaction in order to mark a point where you want to return to. This method returns the FragmentTransaction instance for chain-ability only.

    Then Return with the popBackStackImmediate(tag: String, flag: int): void method from the FragmentManager. The tag is what you specified before. The flag is either the constant POP_BACK_STACK_INCLUSIVE to include the transaction marked or 0.

    Example

    What follows is an example with the following layout having a FrameLayout with id content_frame where the fragments are loaded into.

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_below="@id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    </RelativeLayout>
    

    The code below marks a fragment by it's fragment class name when replacing the content of the layout element with id content_frame.

    public void loadFragment(final Fragment fragment) {
        
        // create a transaction for transition here
        final FragmentTransaction transaction = getSupportFragmentManager()
                .beginTransaction();
                
        // put the fragment in place
        transaction.replace(R.id.content_frame, fragment);
    
        // this is the part that will cause a fragment to be added to backstack,
        // this way we can return to it at any time using this tag
        transaction.addToBackStack(fragment.getClass().getName());
    
        transaction.commit();
    }
    

    And to complete this example a method that allows you to get back to that exact same fragment using the tag when you loaded it.

    public void backToFragment(final Fragment fragment) {
    
        // go back to something that was added to the backstack
        getSupportFragmentManager().popBackStackImmediate(
                fragment.getClass().getName(), 0);
        // use 0 or the below constant as flag parameter
        // FragmentManager.POP_BACK_STACK_INCLUSIVE);
    
    }
    

    When implementing this for real you might want to add a null check on the fragment parameter ;-).

    0 讨论(0)
  • 2021-01-30 11:35

    This is how I do it..

    With FragmentA.java and any other fragments.

    Replace your fragment with its class name as tag:

    private void showFragment(Fragment fragment){
            if(fragment != null){
                getSupportFragmentManager().beginTransaction().replace(R.id.container,fragment,fragment.getClass().getSimpleName()).commit();
            }
        }
    

    Now in onBackPressed():

    @Override
        public void onBackPressed()
        {
    if(getSupportFragmentManager().findFragmentByTag("FragmentA") == null)
                showFragment(new FragmentA());
            else
                super.onBackPressed();
        }
    
    0 讨论(0)
提交回复
热议问题