Android Fragment Back Stack Example

Android OS provides a back stack function for Activity, it also provides the back stack function for Fragment. If you add one Fragment into the back stack, when you press the android device back menu, you can find the Fragment that is saved in the back stack popup. Until all the saved Fragments in the back stack popup, then the activity will exit.

android-fragment-back-stack-diagram

1. Fragment Back Stack Example.

  1. This example contains one activity and three fragments.
  2. Each fragment includes a button and an input text box.
  3. When clicking the button it will either show a hidden or create a new target fragment.
  4. When clicking the back menu, the stacked fragments will be popup by order, if the fragment is hidden in the stack ( fragment two ), then the text in the input box will be saved also.
  5. If the fragment is replaced in the stack ( fragment one ), because the replace action will delete the previous fragment ( fragment one ) and then add a new fragment ( fragment two ), so the input text in the previous fragment will not be saved.
  6. You can use the below code to put a fragment into the back stack.
    fragmentTransaction.addToBackStack(null);
  7. If you click the “Go To Fragment One” button in Fragment three, because Fragment one is at the bottom of the back stack, so it will remove all the above Fragments in the back stack and show Fragment One again.
  8. So when you go to Fragment Two again, you will find the input text disappear because it is newly created.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/99V1o-8luPo

2. Fragment Back Stack Example Source Code.

  1. activity_fragment_back_stack.xml
  2. This is the main activity layout XML file.
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <FrameLayout
            android:id="@+id/fragment_back_stack_frame_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>
  3. fragment_back_stack_one.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="This is Fragment One."
            android:textSize="20dp"
            android:gravity="center"
            android:textColor="@android:color/holo_red_light"/>
    
        <EditText
            android:hint="Input text here."
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/fragment_back_stack_one_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Go To Fragment Two"
            android:layout_gravity="center"
            android:textSize="20dp"/>
    
    </LinearLayout>
  4. fragment_back_stack_two.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="This is Fragment Two."
            android:textSize="20dp"
            android:gravity="center"
            android:textColor="@android:color/holo_green_light"/>
    
        <EditText
            android:hint="Input text here."
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/fragment_back_stack_two_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Go To Fragment Three"
            android:layout_gravity="center"
            android:textSize="20dp"/>
    
    </LinearLayout>
  5. fragment_back_stack_three.xml
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="This is Fragment Three."
            android:textSize="20dp"
            android:gravity="center"
            android:textColor="@android:color/holo_blue_light"/>
    
        <EditText
            android:hint="Input text here."
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/fragment_back_stack_three_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Go To Fragment One"
            android:layout_gravity="center"
            android:textSize="20dp"/>
    
    </LinearLayout>
  6. FragmentBackStackActivity.java: This is the main activity java file.
    package com.dev2qa.example.fragment.backstack;
    
    import android.os.Bundle;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v7.app.AppCompatActivity;
    
    import com.dev2qa.example.R;
    import com.dev2qa.example.util.FragmentUtil;
    
    public class FragmentBackStackActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_fragment_back_stack);
    
            setTitle("dev2qa.com - Fragment Back Stack Example.");
    
            // Get FragmentManager and FragmentTransaction object.
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            // Create FragmentOne instance.
            FragmentOne fragmentOne = new FragmentOne();
    
            // Add fragment one with tag name.
            fragmentTransaction.add(R.id.fragment_back_stack_frame_layout, fragmentOne, "Fragment One");
            fragmentTransaction.commit();
    
            FragmentUtil.printActivityFragmentList(fragmentManager);
    
        }
    }
  7. FragmentOne.java
    package com.dev2qa.example.fragment.backstack;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    
    import com.dev2qa.example.R;
    import com.dev2qa.example.util.FragmentUtil;
    
    public class FragmentOne extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View retView = inflater.inflate(R.layout.fragment_back_stack_one, container, false);
    
            final FragmentManager fragmentManager = getFragmentManager();
    
            Button gotoFragmentTwoBtn = (Button)retView.findViewById(R.id.fragment_back_stack_one_button);
            gotoFragmentTwoBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    Fragment fragmentTwo = FragmentUtil.getFragmentByTagName(fragmentManager, "Fragment Two");
    
                    // Because fragment two has been popup from the back stack, so it must be null.
                    if(fragmentTwo==null)
                    {
                        fragmentTwo = new FragmentTwo();
                    }
    
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                    // Replace fragment one with fragment two, the second fragment tag name is "Fragment Two".
                    // This action will remove Fragment one and add Fragment two.
                    fragmentTransaction.replace(R.id.fragment_back_stack_frame_layout, fragmentTwo, "Fragment Two");
    
                    // Add fragment one in back stack.So it will not be destroyed. Press back menu can pop it up from the stack.
                    fragmentTransaction.addToBackStack(null);
    
                    fragmentTransaction.commit();
    
                    FragmentUtil.printActivityFragmentList(fragmentManager);
                }
            });
    
            return retView;
        }
    }
  8. FragmentTwo.java
    package com.dev2qa.example.fragment.backstack;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    
    import com.dev2qa.example.R;
    import com.dev2qa.example.util.FragmentUtil;
    
    public class FragmentTwo extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View retView = inflater.inflate(R.layout.fragment_back_stack_two, container, false);
    
            final FragmentManager fragmentManager = getFragmentManager();
    
            Button gotoFragmentThreeBtn = (Button)retView.findViewById(R.id.fragment_back_stack_two_button);
            gotoFragmentThreeBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    FragmentThree fragmentThree = new FragmentThree();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
                    FragmentUtil.printActivityFragmentList(fragmentManager);
    
                    // Get fragment two if exist.
                    Fragment fragmentTwo = FragmentUtil.getFragmentByTagName(fragmentManager, "Fragment Two");
                    if(fragmentTwo!=null) {
                        Log.d(FragmentUtil.TAG_NAME_FRAGMENT, "Fragment Two exist in back stack, will hide it now.");
                        // Hide fragment two. Only hide not destroy.
                        // When user type back menu in Fragment three,
                        // this hidden Fragment will be shown again with input text saved.
                        fragmentTransaction.hide(fragmentTwo);
                    }
                    // Add Fragment with special tag name.
                    fragmentTransaction.add(R.id.fragment_back_stack_frame_layout, fragmentThree, "Fragment Three");
                    // Add fragment two in back stack.
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();
                }
            });
    
            return retView;
        }
    }
  9. FragmentThree.java
    package com.dev2qa.example.fragment.backstack;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v7.app.AlertDialog;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    
    import com.dev2qa.example.R;
    import com.dev2qa.example.util.FragmentUtil;
    
    public class FragmentThree extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View retView = inflater.inflate(R.layout.fragment_back_stack_three, container, false);
    
            final FragmentManager fragmentManager = getFragmentManager();
    
            Button gotoFragmentOneBtn = (Button)retView.findViewById(R.id.fragment_back_stack_three_button);
            gotoFragmentOneBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    AlertDialog alertDialog = new AlertDialog.Builder(getActivity().getApplicationContext()).create();
    
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
                    FragmentUtil.printActivityFragmentList(fragmentManager);
    
                    // Get fragment one if exist.
                    Fragment fragmentOne = new FragmentOne();
    
                    fragmentTransaction.replace(R.id.fragment_back_stack_frame_layout, fragmentOne, "Fragment One");
    
                    // Do not add fragment three in back stack.
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();
                }
            });
    
            return retView;
        }
    }
  10. FragmentUtil.java: This is a util java class that provides methods to get existing fragments by the tag name, print debug log, etc.
    package com.dev2qa.example.util;
    
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.util.Log;
    
    import java.util.List;
    
    public class FragmentUtil {
    
        public final static String TAG_NAME_FRAGMENT = "ACTIVITY_FRAGMENT";
    
        // Get exist Fragment by it's tag name.
        public static Fragment getFragmentByTagName(FragmentManager fragmentManager, String fragmentTagName)
        {
            Fragment ret = null;
    
            // Get all Fragment list.
            List<Fragment> fragmentList = fragmentManager.getFragments();
    
            if(fragmentList!=null)
            {
                int size = fragmentList.size();
                for(int i=0;i<size;i++)
                {
                    Fragment fragment = fragmentList.get(i);
    
                    if(fragment!=null) {
                        String fragmentTag = fragment.getTag();
    
                        // If Fragment tag name is equal then return it.
                        if (fragmentTag.equals(fragmentTagName)) {
                            ret = fragment;
                        }
                    }
                }
            }
    
            return ret;
        }
    
        // Print fragment manager managed fragment in debug log.
        public static void printActivityFragmentList(FragmentManager fragmentManager)
        {
            // Get all Fragment list.
            List<Fragment> fragmentList = fragmentManager.getFragments();
    
            if(fragmentList!=null)
            {
                int size = fragmentList.size();
                for(int i=0;i<size;i++)
                {
                    Fragment fragment = fragmentList.get(i);
    
                    if(fragment!=null) {
                        String fragmentTag = fragment.getTag();
                        Log.d(TAG_NAME_FRAGMENT, fragmentTag);
                    }
                }
    
                Log.d(TAG_NAME_FRAGMENT, "***********************************");
            }
        }
    }
3 1 vote
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x