Chapter Five
FRAGMENT
Fragment
Assume you want your app to behave differently depending on
whether it’s running on a phone or a tablet? In such cases you need
Fragments.
The aim of Fragment is to create modular code in our Application.
The code can be reused by different activities.
Fragments have their own lifecycle and layouts or UI components
A Fragment is a class that contains a portion of an application’s user
interface, which can be added as part of an app UI.
Fragments also have their logic and can thus, accept and handle
different events.
E.g. The standard date picker is a Fragment—an instance of Dialog
Fragment, a subclass of Fragment—that enables the user to input a date.
The standard date picker shows a dialog window floating on top of the
Activity window.
Example
Cont’d[Example]
Activity vs Fragment
Activity Fragment
Activity is an application component that The fragment is only part of an activity, it
gives a user interface where the user can basically contributes its UI to that activity.
interact.
Fragment is dependent on activity. It
Activity is not dependent on fragment can’t exist independently.
we need to mention all activity it in the Fragment is not required to mention in the
manifest.xml file manifest file
Activity is not light weight. The fragment is the light weight.
We can’t create multi-screen UI without After using multiple fragments in a single
using fragment in an activity. activity, we can create a multi-screen UI.
Features of Fragments
Before fragments we can show a single Activity on the screen at once.
But with the help of fragments we can divide the screen and controls
different parts separately.
Reuse a Fragment. We can write the Fragment code once, and reuse
the Fragment in more than one Activity without having to repeat code.
Add or remove a Fragment dynamically. Add, replace, or remove a
Fragment from An activity as needed.
Integrate a mini-UI within the Activity. Integrate a Fragment with an
Activity UI or overlay the UI, so that the user can interact with the
Fragment UI without leaving the Activity.
Retain data instances after a configuration change. Since a Fragment
has its own lifecycle, it can retain an instance of its data after a
configuration change (such as changing the device orientation).
Represent sections of a layout for different screen sizes. Encapsulating
an interactive UI within a Fragment makes it easier to display the
interactive UI on different screen sizes.
Fragment Life Cycle
Cont’d
N.B. A Fragment lifecycle is very similar to an Activity life cycle’s., ,
but it has a few extra steps. This is because it needs to interact with
the lifecycle of the activity that contains it.
As with an Activity, you can save the variable assignments in a
Fragment.
onCreateView(): The onCreateView() method returns a View object
that represents the fragment’s user interface. It gets called when
Android is ready to instantiate the user interface, and it takes three
parameters:
1) Layout inflator: used for inflating the fragment layout. Inflating the
layout turns your XML views into Java Objects.
2) View Group: This is the View Group in the activity’s layout that will
contain the fragment.
3) Bundle: . This is used if you’ve previously saved the fragment’s state,
and want to reinstate it.
Use Activity context on Fragment
The Activity context is used by a fragment to get a reference to its
hosting Activity.
getActivity() is used to achieve this task
View listView = getActivity().findViewById(R.id.list);
N.B. getActivity() when the Fragment is not attached to an Activity,
getActivity() returns null.
Use Fragment Methods in the host Activity
your Activity can call methods in the Fragment by acquiring a reference
to the Fragment from FragmentManager or Support Fragment Manager,
using findFragmentById()
ExampleFragment fragment = (ExampleFragment)
getFragmentManager().findFragmentById(R.id.example_fragment);
Fragment to Fragment communication is handled through Activity
Fragment inherit lifecycle methods
The fragment class doesn’t extend the Activity class.
Some methods that are available to activities aren’t available to
fragments.
Fragment class doesn’t implement the Context
Class. So, unlike an activity, a fragment isn’t a type
of context and therefore doesn’t have direct access
to global information about the application environment.
Instead, fragments must access this information using the
context of other objects such as its parent activity.
Exercise
Create WorkoutDetail Fragment
Create WorkoutList Fragment
Coordinate the fragments to display the correct workout
First we need to create Main Activity and Detail Activity
Main Activity is used for WorkoutList Fragement
Detail Activity is used for WorkoutDetail Fragment.
We start by working on the fragment for DetailActivity first, and adding
a button to MainActivity will give us an easy way of navigating from
MainActivity to DetailActivity.
In your activity_main add button, in the activity code start Intent to
shift into Detail Activity
Workout Detail Fragment
In Your Package name, New...→Fragment→Fragment (Blank).
<LinearLayout
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/workout_title"
android:id="@+id/textTitle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/workout_description"
android:id="@+id/textDescription" />
DetailActivity Layout
layout file requires a single view or view group as its root element. If
your activity only contains a fragment, the fragment itself can be
the root element.
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.hfad.workout.WorkoutDetailFragment“
android:id="@+id/detail_frag"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Workout class public class WorkoutDetailFragment extends F
{
private long workoutId;
(refer page no. 360) @Override
public View onCreateView(LayoutInflater in
Fragments don’t include ViewGroup container,
a findViewById() method, for instance. Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_worko
To get a reference to a fragment’s views, container, false);
we first have to get a reference to the }
@Override
fragment’s root view using the getView() public void onStart() {
super.onStart();
method, and use that to find its child views.
View view = getView();
if (view != null) {
TextView title = (TextView)
view.findViewById(R.id.textTitle);
Workout workout = Workout.workouts[(int) wo
title.setText(workout.getName());
TextView description = (TextView)
view.findViewById(R.id.textDescription
description.setText(workout.getDescriptio
}
WorkList Fragment
A list fragment is a fragment that contains only a list
A list fragment is a type of fragment that specializes in working with
a list view. It has a default layout that contains the list view.
Advantage of List Fragment
You don’t to create your own Layout
There is no XML layout needed. List Fragment define there own
layout programmatically.
getListView() method is used to access the list view in your fragment
code
You don’t have to implement your own event Listener
List Fragment class automatically implements an event listener that
listens for when items in the list view are clicked. We just need to
implement onListItemClick() method.
Add data to ListView Fragment
We want to supply the list view in WorkoutListFragment with an array
of workout names
ArrayAdapter can be used to bind our workout names(array) in list
view.
Unlike an Activity we cant use this to pass the current context to the
array adapter. Why?
The solution is use another object getContext() method to get a
reference to the current context.
If the adapter is created on the fragment’s onCreateView()
method, the getContext() method of the onCreateView()
LayoutInflator parameter can be used to get the context instead.
The last step is to set adapter in the listview. We use setListAdapter()
method.
WorkListFragment
public class WorkoutListFragment extends ListFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,
Bundle savedInstanceState) {
String[] names = new String[Workout.workouts.length];
for (int i = 0; i < names.length; i++) {
names[i] = Workout.workouts[i].getName();
}
ArrayAdapter<String> adapter = new ArrayAdapter<>(
inflater.getContext(), android.R.layout.simple_list_item_1,
names);
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
}
Main Activity Layout
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.hfad.workout.WorkoutListFragment“
android:id="@+id/detail_frag"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Connect the list to detail
3 steps
Add code to WorkoutListFragment that waits for a workout to be
clicked.
When that code runs, call some code in MainActivity.java that will
start DetailActivity, passing it the Id of the Workout
Get DetailActivity to pass the ID to WorkoutDetailFragment so that the
fragment can display details of the correct workout.
By defining Interface in our work list fragment we can communicate
the work list with main activity with little effort as well we can reuse
code.
ListView Fragment
Define the Listener interface
static interface Listener {
void itemClicked(long id);
};
Register the listener: We need to save a reference to the activity
WorkoutListFragment.
private Listener listener;
public void onAttach(Context context) {
super.onAttach(context);
this.listener = (Listener)context;
}
Cont’d
Respond to clicks: When an item in WorkoutListFragment gets
clicked, we want to call the listener’s itemClicked() method.
public void onListItemClick(ListView listView, View itemView, int position,
long id) {
if (listener != null) {
listener.itemClicked(id);
}
}
Main Activity
Main Activity needs to implement the interface
public class MainActivity extends AppCompatActivity
implements WorkoutListFragment.Listener {
@Override
public void itemClicked(long id) {
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra(“id”, (int)id);
startActivity(intent);
}