Android Fragment Transaction (One Activity | One container With Multiple Fragment)

By | February 6, 2017

In the past we have seen how to Design UI using fragment form varying factors (portrait and landscape). In this tutorial we will see how to add multiple fragment into single container inside Activity which will be maintained in stack format (Last In First Out).

So now the question why multiple fragment instead we can have multiple Activities  ? Reason, Fragment comes very handy which can be used to respond to user input, varying form factors (phone or tablet) and other issues, such as, the orientation of the device. In portrait mode an app may show itself in a different manner to say landscape.

1. Launcher Fragment | Main Fragment | Default Fragment

XML Layout

Create XML Layout (res/layout/fragment_main.xml)  with one TextView and Buttons

file : fragment_main.xml

<LinearLayout 
    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:gravity="center"
    android:orientation="vertical"
    tools:context="com.tutorialsbuzz.fragmenttransaction.MainActivityFragment">

    <TextView
        style="@style/lableStyle"
        android:text="@string/lable_in_mainfragment" />

    <Button
        android:id="@+id/button01"
        style="@style/buttonStyle"
        android:text="@string/lable_move_fragment01" />

    <Button
        android:id="@+id/button02"
        style="@style/buttonStyle"
        android:text="@string/lable_move_fragment02" />

    <Button
        android:id="@+id/button03"
        style="@style/buttonStyle"
        android:text="@string/lable_move_fragment03" />

</LinearLayout>

Fragment

  • Set the content of the MainActivityFragment with above defined XML Layout , This fragment will be loaded first in container inside host activity which we will find in the below code inside activity class .
  • Set the onclick listener for the three button and inside onclick event  load appropriate fragment into container by calling showFragment method of host activity by passing fragment object as parameter .
  • As you can see the showFragment method is called inside onclick event , this method is defined inside the host activity class which contains the logic to loading the fragment which is passed as a parameter to it  .
  • Inside the onResume Call the setToolbarTitle to set Toolbar title and Call the disableNavigationIcon (disabling navigation icon as it is launcher fragment or you can set home icon ) .

file : MainActivityFragment.java

package com.tutorialsbuzz.fragmenttransaction;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MainActivityFragment extends Fragment implements View.OnClickListener {

    public MainActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_main, container, false);

        view.findViewById(R.id.button01).setOnClickListener(this);
        view.findViewById(R.id.button02).setOnClickListener(this);
        view.findViewById(R.id.button03).setOnClickListener(this);

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        ((MainActivity) getActivity()).disableNavigationIcon();
        ((MainActivity) getActivity()).setToolbarTitle(R.string.MainFragmentTitle);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.button01:
                //Move to Fragment 01
                ((MainActivity) getActivity()).showFragment(new FragmentExample1());
                break;

            case R.id.button02:
                //Move to Fragment 02
                ((MainActivity) getActivity()).showFragment(new FragmentExample2());
                break;

            case R.id.button03:
                //Move to Fragment 03
                ((MainActivity) getActivity()).showFragment(new FragmentExample3());
                break;

        }

    }
}

mainfragment

2. Fragment One

XML Layout

Create XML Layout (res/layout/fragment_example_1.xml) with one TextView and Two Buttons

file : fragment_example_1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_orange_light"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        style="@style/lableStyle"
        android:text="@string/lable_in_fragment_01"
        android:textColor="@android:color/white" />

    <Button
        android:id="@+id/btn_f1_01"
        style="@style/buttonStyle"
        android:text="@string/lable_move_fragment02" />

    <Button
        android:id="@+id/btn_f1_02"
        style="@style/buttonStyle"
        android:text="@string/lable_move_fragment03" />

</LinearLayout>

Fragment

  • Set the content of the FragmentExample1 with above defined XML Layout.
  • Set the onclick listener for the two button and inside onclick event load appropriate fragment into container by calling showFragment method of host activity by passing fragment object as parameter .
  • Inside the onResume Call the setToolbarTitle to set Toolbar title and Call the enableNavigationIcon.

file : FragmentExample1.java

package com.tutorialsbuzz.fragmenttransaction;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentExample1 extends Fragment implements View.OnClickListener {

    public FragmentExample1() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_example_1, container, false);

        view.findViewById(R.id.btn_f1_01).setOnClickListener(this);
        view.findViewById(R.id.btn_f1_02).setOnClickListener(this);

        return view;
    }


    @Override
    public void onResume() {
        super.onResume();
        ((MainActivity) getActivity()).setToolbarTitle(R.string.Fragment01Title);
        ((MainActivity) getActivity()).enableNavigationIcon();
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.btn_f1_01:
                //Move to Fragment 02
                ((MainActivity) getActivity()).showFragment(new FragmentExample2());
                break;

            case R.id.btn_f1_02:
                //Move to Fragment 03
                ((MainActivity) getActivity()).showFragment(new FragmentExample3());
                break;
        }
    }
}

fragment1

3. Fragment Two

XML Layout

Create XML Layout (res/layout/fragment_example_2.xml) with one TextView and one Buttons

file : fragment_example_2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_dark"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        style="@style/lableStyle"
        android:text="@string/lable_in_fragment_02"
        android:textColor="@android:color/white" />
    
    <Button
        android:id="@+id/btn_f2_01"
        style="@style/buttonStyle"
        android:text="@string/lable_move_fragment03" />
    
</LinearLayout>

Fragment

  • Set the content of the FragmentExample1 with above defined XML Layout.
  • Set the onclick listener for the two button and inside onclick event load appropriate fragment into container by calling showFragment method of host activity by passing fragment object as parameter .
  • Inside the onResume Call the setToolbarTitle to set Toolbar title and Call the enableNavigationIcon.

file : FragmentExample2.java

package com.tutorialsbuzz.fragmenttransaction;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentExample2 extends Fragment {

    public FragmentExample2() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_example_2, container, false);

        view.findViewById(R.id.btn_f2_01).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //move to fragment3
                ((MainActivity) getActivity()).showFragment(new FragmentExample3());
            }
        });

        return view;
    }


    @Override
    public void onResume() {
        super.onResume();
        ((MainActivity) getActivity()).enableNavigationIcon();
        ((MainActivity) getActivity()).setToolbarTitle(R.string.Fragment02Title);
    }
}

fragment2

4. Fragment Three

XML Layout

Create XML Layout (res/layout/fragment_example_3.xml) with one TextView .

file : fragment_example_3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_green_dark"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        style="@style/lableStyleWhite"
        android:text="@string/lable_in_fragment_03" />

</LinearLayout>

Fragment

  • Set the content of the FragmentExample3 with above defined XML Layout.
  • Inside the onResume Call the setToolbarTitle to set Toolbar title and Call the enableNavigationIcon.

file : FragmentExample3.java

package com.tutorialsbuzz.fragmenttransaction;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentExample3 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_example_3, container, false);
        return view;
    }
    
    @Override
    public void onResume() {
        super.onResume();
        ((MainActivity) getActivity()).enableNavigationIcon();
        ((MainActivity) getActivity()).setToolbarTitle(R.string.Fragment03Title);

    }
}

fragment3

XML Layout Fragment
1.  Launcher Fragment fragment_main.xml MainActivityFragment.java
2. Fragment One fragment_example_1.xml FragmentExample1.java
3. Fragment Two fragment_example_2.xml FragmentExample2.java
4. Fragment Three fragment_example_3.xml FragmentExample3.java

5. Activity

XML Layout

Create XML Layout (res/layout/activity_main.xml) add toolbar widget and framelayout (container for fragment).

file : activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.tutorialsbuzz.fragmenttransaction.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

Container

Create XML Layout (res/layout/content_main.xml) add framelayout to it which will be a container for fragments
and this xml layout is included in above defined activity_main xml layout.

file : content_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

MainActivity

  • This activity will be a host activity for the above defined fragments.
  • Set the Content of MainActivity with above defined XML Layout .
  • Now Inside MainActivity class we will defined methods which contains logic to perform fragment transaction .
    1. showFragment: This method takes fragment object as parameter and loads it in fragment container .
    2. backstackFragment : This methods decrement the back stack count ( backstackFragment update the stack not the UI ,So we have to call removeCurrentFragment after upadting stack count ).
    3. removeCurrentFragment : This method contains the logic for removing fragment from container , This method is called inside backstackFragment .
  • enableNavigationIcon : This methods  is called to  enable toolbar navigation icon and set onclick listener for icon .
  • disableNavigationIcon : This method is called to remove toolbar navigation icon .
  • setToolbarTitle : This method is called to set toolbar title by passing string res .

file : MainActivity.java

package com.tutorialsbuzz.fragmenttransaction;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        showFragment(new MainActivityFragment());
    }

    protected void showFragment(Fragment fragment) {

        String TAG = fragment.getClass().getSimpleName();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.mainContainer, fragment, TAG);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commitAllowingStateLoss();
    }

    protected void backstackFragment() {
        Log.d("Stack count", getSupportFragmentManager().getBackStackEntryCount() + "");
        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
            finish();
        }
        getSupportFragmentManager().popBackStack();
        removeCurrentFragment();
    }

    private void removeCurrentFragment() {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        Fragment currentFrag = getSupportFragmentManager()
                .findFragmentById(R.id.mainContainer);

        if (currentFrag != null) {
            transaction.remove(currentFrag);
        }
        transaction.commitAllowingStateLoss();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
            finish();
        }
    }

    protected void enableNavigationIcon() {

        toolbar.setNavigationIcon(R.mipmap.back_arrow);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                backstackFragment();
            }
        });
    }

    protected void disableNavigationIcon() {
        toolbar.setNavigationIcon(null);
    }

    protected void setToolbarTitle(int resID) {
        toolbar.setTitle(resID);
    }

}

GitHub Link : https://github.com/hdpavan/FragmentTransaction 

  • andreaAMADO

    Thanks