Android Working With Fragments

This tutorial is about how to create a fragment and include it in an activity with the help of an example.

Create a fragment class

To create a fragment, we have to define a fragment class, which extends the class Fragment and overrides the necessary methods.

class FragmentOne : Fragment() {

    override fun onCreateView(

        inflater: LayoutInflater, container: ViewGroup?,

        savedInstanceState: Bundle?

    ): View? {

        // Inflate the layout for this fragment

        return inflater.inflate(R.layout.fragment_one, container, false)

    }

FragmentOne: subclass of Fragment.

fragment_one:  layout of fragmentOne, which is defined in a separate XML file with the name fragment_one.xml.

Add a fragment to an activity

To add a fragment to any activity, you can follow any of the following 2 approaches:

  • Add a fragment via XML
  • Add a fragment programmatically

In either case, you need to add a FragmentContainerView which extends the FrameLayout view group.

It is strongly recommended to always use a FragmentContainerView as the container for fragments, as FragmentContainerView includes fixes specific to fragments that other view groups such as FrameLayout do not provide.

Add a fragment via XML

  • To add a fragment to your activity layout’s XML, use a FragmentContainerView element.
  • In FragmentContainerView, android: name or class attribute specifies the class name of the Fragment to instantiate.
<androidx.fragment.app.FragmentContainerView

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/fragment_container_view"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:name="com.example.ExampleFragment" />

When the activity’s layout is inflated, the specified fragment is instantiated, onInflate() is called on the newly instantiated fragment, and a FragmentTransaction is created to add the fragment to the FragmentManager.

Implementation of Fragment via XML

In this example, we will see how to statically add two fragments to an activity, by adding two FragmentContainerView elements directly in our app’s main layout XML file.

The activity_main.xml defines the activity layout which consists of two FragmentContainerView elements with different class attributes (FragmentOne and FragmentTwo).

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fcv_one"
        class="com.c1ctech.androidfragmentdemo.FragmentOne"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="5" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fcv_two"
        class="com.c1ctech.androidfragmentdemo.FragmentTwo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="5" />

</LinearLayout>

The fragment_one.xml defines the layout of the fragment with the name FragmentOne.

fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<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:background="@android:color/holo_orange_light"
    tools:context=".FragmentOne">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="FragmentOne"
        android:textColor="@android:color/white"
        android:textSize="30sp"
        android:textStyle="bold" />

</RelativeLayout>

The FragmentOne defines the subclass of Fragment corresponding to the layout fragment_one.xml. 

FragmentOne.kt

package com.c1ctech.androidfragmentdemo
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class FragmentOne : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_one, container, false)
    }
}

Similarly, the layout XML file and the class for the second fragment ( FragmentTwo ) will be:

fragment_two.xml

<?xml version="1.0" encoding="utf-8"?>
<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:background="@android:color/holo_blue_bright"
    tools:context=".FragmentTwo">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="FragmentTwo"
        android:textColor="@android:color/white"
        android:textSize="30sp"
        android:textStyle="bold" />

</RelativeLayout>

FragmentTwo.kt

package com.c1ctech.androidfragmentdemo

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class FragmentTwo : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_two, container, false)
    }
}

There is no need to make any changes in the activity while adding the fragment via XML to an activity.

When you run the app it will look like this:

An activity containing two fragments with different UI.

Add a fragment programmatically

To dynamically add a fragment to your activity’s layout, the layout should include a FragmentContainerView to serve as a fragment container, as shown in the following example:

<androidx.fragment.app.FragmentContainerView

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/fragment_container_view"

    android:layout_width="match_parent"

    android:layout_height="match_parent" />
  • Instead of using android:name or class attribute ( instantiate the specific fragment automatically), a FragmentTransaction is used to instantiate a fragment and add it to the activity’s layout.
  • While your activity is running, you can make fragment transactions such as adding, removing or replacing a fragment.
Implementation of Fragment programmatically

In this example, we will see how to dynamically add fragments to an activity on click of buttons, by adding only one FragmentContainerView element in our app’s main layout XML file.

The activity_main.xml defines the activity layout which consists of a FragmentContainerView element and two buttons, on click of which we will add different fragments in FragmentContainerView element at run time.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_fragmentOne"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="FragmentOne"
        android:textAllCaps="false"
        android:textSize="20sp"
        android:background="@android:color/holo_orange_light"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_fragmentTwo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:text="FragmentTwo"
        android:textAllCaps="false"
        android:textSize="20sp"
        android:background="@android:color/holo_blue_bright"
        app:layout_constraintEnd_toEndOf="@+id/btn_fragmentOne"
        app:layout_constraintStart_toStartOf="@+id/btn_fragmentOne"
        app:layout_constraintTop_toBottomOf="@+id/btn_fragmentOne" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_fragmentTwo" />

</androidx.constraintlayout.widget.ConstraintLayout>

The code for the main activity class MainActivity.kt will be as follows:

MainActivity.kt

package com.c1ctech.androidfragmentdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.fragment.app.add
import androidx.fragment.app.commit
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn_fragmentOne.setOnClickListener {
            supportFragmentManager.commit {
                add<FragmentOne>(R.id.fragment_container_view)
            }
        }

        btn_fragmentTwo.setOnClickListener {
            supportFragmentManager.commit {
                add<FragmentTwo>(R.id.fragment_container_view)
            }
        }
    }
}

In the above code, to add the fragment dynamically to the activity:

  • The FragmentManager is used to create a FragmentTransaction.
  • Then, to instantiate the fragment FragmentTransaction.add() is used, passing in the ViewGroup ID of the container in the layout and the fragment class we want to add and then commited the transaction.

When you run the app it will look like this:

Button FragmentOne is clicked
Button FragmentTwo is clicked

Leave a Reply