Last week, our Android candidates attended DoodleBlue Interview.  In this post, we are going to discuss about DoodleBlue Android Interview  Questions with Answers.  One of the interview questions is “What is Fragment in Android”.  Let us discuss about that here.

DoodleBlue  Android Interview  Questions with Answers – What is Fragment in Android

What is fragment in android?
Fragment is a portion of user interface in a FragmentActivity. By merging various fragments in an activity to build multi-pane UI, we can reprocess the fragment in various activities.

Characteristics of Fragment:

1.A fragment has its own design and style with its own life cycle callbacks.
2.Fragments can be included or excluded in an activity even when the activity is executing.
3.When the activity is paused the fragments available in the activity is also passed, as the fragment’s lifecycle is closely linked with the lifecycle of the host activity.
4.A fragment can implement a behaviour that has no user interface component.

Design philosophy:

• Fragments were introduced by Android in Android 3.0 (Honeycomb version of API level 11), chiefly to support more lively and adjustable UI designs on large screens.
• Since the large screen gadget is much wider than that of a handset, there’s more area to merge and shift UI components.
• Fragments allow such designs without managing complex changes to the view hierarchy.
• Modification of the activity’s appearance at runtime and preservation of those variations in a back stack that’s managed by the activity is made possible by dividing the layout of an activity into fragments.
• This can be done through the fragment support library.

fragment

Fragment lifecycle:

fragment

Fragments have their very own lifecycle called callbacks, which is closely linked to the lifecycle of the activity.

The methods used for overriding in the fragment class are as follows;
• onAttach() – a reference to the activity which uses the fragment for further initialization purpose is got by this method.
• onCreate() – while creating the fragment, this method is called by the system to initialize essential components of the fragment that needs to be retained whenever the fragment is paused or stopped, then resumed.
• onCreateView() – when the fragment draws its user interface for the first time, this method is called by the system. The View component must be returned form this method that is the root of the fragment’s layout in order to draw UI for your fragment.
• onActivityCreated() – After the onCreateView() method , this method is called. Here you can instantiate objects requiring a Context object.
• onStart() – Once the fragment gets visible, this method is called.
• onResume() – This method is called when the fragment becomes active.
• onPause() – This method is called by the system to indicate that the user is leaving the fragment. Any changes that should be persisted beyond the current user session have to be committed here.
• onStop() – The fragment is stopped by this method.
• onDestroyView() – The FragmentView is destroyed after call of this method.
• onDestroy() – The final clean up of the fragment’s state is done by call of this method, but not guaranteed to be called by the Android platform.

Creation of fragments:

1. The fragments needs to be created before its usage, the simple steps in its creation are given below;
2. Deciding the number of fragments to be created is the first step in creating a fragment.
3. Based on the number of fragments, the classes which will extend the Fragment class is created.
4. The layout files are created in XML files, in correspondence with each fragment. They have the layout for the defined fragments.
5. Finally, the activity file is modifies to define the actual logic of replacing fragments according to the requirement.

Example:
Lets take an example of creating fragments for two modes of a device namely, portrait and landscape.
The main activity applies a layout in the usual way, during onCreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.fragment_layout);
}

The layout is applied in fragment_layout.xml:

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”horizontal”
android:layout_width=”match_parent” android:layout_height=”match_parent”>

<fragment class=”com.example.android.apis.app.FragmentLayout$TitlesFragment”
android:id=”@+id/titles” android:layout_weight=”1″
android:layout_width=”0px” android:layout_height=”match_parent” />

<FrameLayout android:id=”@+id/details” android:layout_weight=”1″
android:layout_width=”0px” android:layout_height=”match_parent”
android:background=”?android:attr/detailsElementBackground” />

</LinearLayout>
The layout above is used only for the landscape screen configuration, by saving it at res/layout-land/fragment_layout.xml.

Thus, when the screen is in portrait orientation, the system applies the following layout, which is saved at res/layout/fragment_layout.xml:

<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent” android:layout_height=”match_parent”>
<fragment class=”com.example.android.apis.app.FragmentLayout$TitlesFragment”
android:id=”@+id/titles”
android:layout_width=”match_parent” android:layout_height=”match_parent” />
</FrameLayout>
As you inspect this code, notice that there are two possible behaviors when the user clicks a list item: depending on which of the two layouts is active, it can either create and display a new fragment to show the details in the same activity (adding the fragment to the FrameLayout), or start a new activity (where the fragment can be shown).

public static class TitlesFragment extends ListFragment {
boolean mDualPane;
int mCurCheckPosition = 0;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

// Populate list with our static array of titles.
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));

// Check to see if we have a frame in which to embed the details
// fragment directly in the containing UI.
View detailsFrame = getActivity().findViewById(R.id.details);
mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;

if (savedInstanceState != null) {
// Restore last state for checked position.
mCurCheckPosition = savedInstanceState.getInt(“curChoice”, 0);
}

if (mDualPane) {
// In dual-pane mode, the list view highlights the selected item.
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// Make sure our UI is in the correct state.
showDetails(mCurCheckPosition);
}
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(“curChoice”, mCurCheckPosition);
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
showDetails(position);
}

/**
* Helper function to show the details of a selected item, either by
* displaying a fragment in-place in the current UI, or starting a
* whole new activity in which it is displayed.
*/
void showDetails(int index) {
mCurCheckPosition = index;

if (mDualPane) {
// We can display everything in-place with fragments, so update
// the list to highlight the selected item and show the data.
getListView().setItemChecked(index, true);

// Check what fragment is currently shown, replace if needed.
DetailsFragment details = (DetailsFragment)
getSupportFragmentManager().findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != index) {
// Make new fragment to show this selection.
details = DetailsFragment.newInstance(index);

// Execute a transaction, replacing any existing fragment
// with this one inside the frame.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (index == 0) {
ft.replace(R.id.details, details);
} else {
ft.replace(R.id.a_item, details);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}

} else {
// Otherwise we need to launch a new activity to display
// the dialog fragment with selected text.
Intent intent = new Intent();
intent.setClass(getActivity(), DetailsActivity.class);
intent.putExtra(“index”, index);
startActivity(intent);
}
}
}

The second fragment, DetailsFragment shows the play summary for the item selected from the list from TitlesFragment:

public static class DetailsFragment extends Fragment {
/**
* Create a new instance of DetailsFragment, initialized to
* show the text at ‘index’.
*/
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();

// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt(“index”, index);
f.setArguments(args);

return f;
}

public int getShownIndex() {
return getArguments().getInt(“index”, 0);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
// We have different layouts, and in one of them this
// fragment’s containing frame doesn’t exist. The fragment
// may still be created from its saved state, but there is
// no reason to try to create its view hierarchy because it
// isn’t displayed. Note this isn’t needed — we could just
// run the code below, where we would create and return the
// view hierarchy; it would just never be used.
return null;
}

ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
4, getActivity().getResources().getDisplayMetrics());
text.setPadding(padding, padding, padding, padding);
scroller.addView(text);
text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
return scroller;
}
}
Recall from the TitlesFragment class, that, if the user clicks a list item and the current layout does not include the R.id.details view (which is where the DetailsFragment belongs), then the application starts the DetailsActivity activity to display the content of the item.

Here is the DetailsActivity, which simply embeds the DetailsFragment to display the selected play summary when the screen is in portrait orientation:

public static class DetailsActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE) {
// If the screen is now in landscape mode, we can show the
// dialog in-line with the list so we don’t need this activity.
finish();
return;
}

if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}
}

– To Be Continued.