Working with Fragments: How to use a Fragment in Android?
Fragments can exist within Activities and exist within its lifecycle. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running.
To use fragments, we have to use a FrameLayout
element in the layout XML. In this case, the activity_main.xml is going to have two buttons and one FrameLayout, which will be replaced by the fragment on button click.
<?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:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" 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="in.ghostcode.fragments.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:weightSum="1"> <Button android:id="@+id/fragment_1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5" android:onClick="onClick" android:text="Fragment 1"/> <Button android:id="@+id/fragment_2" style="@style/Widget.AppCompat.Button.Colored" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5" android:onClick="onClick" android:text="Fragment 2"/> </LinearLayout> <FrameLayout android:id="@+id/frame_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
We have to create a layout for the fragment in XML. For the sake of this example, I am going to create 2 xml layouts for the fragments.
<?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:orientation="vertical"> <TextView android:text="Fragment 1" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:id="@+id/textView" android:textSize="24sp"/> </LinearLayout>
<?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:orientation="vertical"> <TextView android:text="Fragment 2" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:id="@+id/textView" android:textSize="24sp"/> </LinearLayout>
We have to create fragments and override the onCreateView() method. In this method, we have to inflate the fragment view using LayoutInflater
. The LayoutInflater
requires 3 parameters:
- ID for an XML layout resource to load
- ViewGroup, which is passed into the onCreateView() method, and
- attachToRoot – Whether the inflated view should be attached to the root parameter? In this case, it is false.
import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class FirstFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.first_fragment, container, false); return view; } }
import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class SecondFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.second_fragment, container, false); return view; } }
Now, once we have created the fragment classes, we have to replace the FrameLayout container with the fragment.
mFragment = new FirstFragment(); // begin transaction to replace fragment FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); // pass the id and the fragment to the replace() method fragmentTransaction.replace(R.id.frame_container, mFragment); // commit the transaction fragmentTransaction.commit();
Check out the MainActivity class below, where we switch between the two fragments:
import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; public class MainActivity extends AppCompatActivity { Fragment mFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mFragment = new FirstFragment(); FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.frame_container, mFragment); fragmentTransaction.commit(); } public void onClick(View view) { int id = view.getId(); switch(id) { case R.id.fragment_1: mFragment = new FirstFragment(); break; case R.id.fragment_2: mFragment = new SecondFragment(); break; } FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.frame_container, mFragment); fragmentTransaction.commit(); } }