Android Fragments: Building dynamic UI, Why to use Fragments?
Fragment is a UI entity attached to Activity. Fragments can be reused by attaching in different activities. Activity can have multiple fragments attached to it. Fragment must be attached to an activity and its lifecycle will depend on its host activity. Multiple fragments attached to host activity can be operated separately such as add or remove or replace them. Fragments operations are managed by FragmentManager and each operation or task on activity is performed with FragmentTransanction. With Fragments you can perform better optimization for your application in order to adapt UI for phone as well as tablets.
Lifecycle of a fragment
onAttach(Activity)
called once the fragment is associated with its activity.onCreate(Bundle)
called to do initial creation of the fragment.onCreateView(LayoutInflater, ViewGroup, Bundle)
creates and returns the view hierarchy associated with the fragment.onActivityCreated(Bundle)
tells the fragment that its activity has completed its ownActivity.onCreate()
.onViewStateRestored(Bundle)
tells the fragment that all of the saved state of its view hierarchy has been restored.onStart()
makes the fragment visible to the user (based on its containing activity being started).onResume()
makes the fragment interacting with the user (based on its containing activity being resumed).
As a fragment is no longer being used, it goes through a reverse series of callbacks:
onPause()
fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.onStop()
fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.onDestroyView()
allows the fragment to clean up resources associated with its View.onDestroy()
called to do final cleanup of the fragment’s state.onDetach()
called immediately prior to the fragment no longer being associated with its activity.
Sample Fragment Application
Create a android project in Eclipse, Name your application an set package. I have used name SampleFragmentApplication
and package name as com.androidsrc.fragment
.
We will attach two fragments to main activity of application. One fragment will be of type ListFragment. ListFragment gives you combo of ListView and Fragment functionality which is very easy to use. In ListFragment, we will set adapter for colors in ListView. On clicking of item of this listview, we will interact with second fragment and set corresponding color to its ImageView.
Lets start with layout files. Modify your res/layout/actvity_main.xml
as below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<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="com.androidsrc.fragment.MainActivity" > <fragment android:id="@+id/fragment_one" android:name="com.androidsrc.fragment.FragmentOne" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <fragment android:id="@+id/fragment_two" android:name="com.androidsrc.fragment.FragmentTwo" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> |
Create layout file for fragment one res/layout/fragment_one.xml
as below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?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" > <ListView android:id="@android:id/list" android:choiceMode="singleChoice" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </LinearLayout> |
Create layout for your second fragment res/layout/fragment_two.xml
as below
1 2 3 4 5 6 7 8 9 10 11 12 |
<?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" > <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> |
Now we are done with layout files. Lets move on to source files.
Inside your package, create two class files FragmentOne.java
which will be extending ListFragment class and another FragmentTwo.java
which will be extending Fragment class.
In FragmentOne.java
, create a string array for colors and in onCreateView(), inflate layout file for this fragment and set adapter to ListView by creating a ArrayAdapter. Make sure to override onListItemClick() so that we can handle click events for list items. Since we want to set color for second fragment’s ImageView to same as item clicked, we find fragment by its id using FragmentManager and setImageViewBackground() with color value as parameter. This function we will define in FragmentTwo.java and update color.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
package com.androidsrc.fragment; import android.app.ListFragment; import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; public class FragmentOne extends ListFragment{ int colors[] = new int[]{Color.RED, Color.DKGRAY, Color.BLUE, Color.GREEN, Color.CYAN, Color.MAGENTA, Color.YELLOW}; String color_name[] = new String[]{"RED", "DKGRAY", "BLUE", "GREEN", "CYAN", "MAGENTA", "YELLOW"}; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Creates and returns the view hierarchy associated with the fragment. View view = inflater.inflate(R.layout.fragment_one, container); ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, color_name); setListAdapter(adapter); return view; //make sure to modify this line from super to inflated view } @Override public void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stub FragmentTwo fragment_two = (FragmentTwo)getFragmentManager().findFragmentById(R.id.fragment_two); fragment_two.setImageViewBackground(colors[position]); super.onListItemClick(l, v, position, id); } } |
For FragmentTwo.java
, we will create a ImageView object which will be initialized while creating view for this fragment. Define setImageViewBackground() in order to set background of ImageView.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
package com.androidsrc.fragment; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; public class FragmentTwo extends Fragment{ private ImageView imgView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Creates and returns the view hierarchy associated with the fragment. View view = inflater.inflate(R.layout.fragment_two, container); imgView = (ImageView)view.findViewById(R.id.imageView); return view; } public void setImageViewBackground(int colorValue) { // TODO Auto-generated method stub if(imgView != null){ imgView.setBackgroundColor(colorValue); } } } |
Finally, lets move on to MainActivity.java
. Not much is required to edit here. Make sure we are calling setContentView().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.androidsrc.fragment; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } |
Run your program. Try changing color of second fragment by clicking listview items from first fragment. Kudos we are done with sample fragment application. For refreshing up topic, Please refer below for its benefits and quick remember points.
Benefits of Fragments over Activity
1. Communication between various fragments is very easier than sending data back and forth between activities.
2. Re-usability – Fragments have very good re-usability. You can use same fragment over different places in your application.
3. UI Customizations – Its very easy to handle or implement functionalities like swipe between views or tab views.
4. Easy to handle state of UI over orientation change of device- Making setRetainInstance(true) will reattach previous fragments to the new instance of activity and retain their state.
Points to remember
- A fragment has its own layout and its own behavior with its own life-cycle and callbacks.
- You can add or remove fragments in an activity while the activity is running.
- You can combine multiple fragments in a single activity to build a multi-pane UI.
- A fragment can be used in multiple activities.
- Fragment life cycle is closely related to the life-cycle of its host activity.
- When the activity is paused, all the fragments available in the activity will also be stopped.
- A fragment can implement a behavior that has no user interface component.