Fragment based Android interview questions and answers

1) Describe 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.

What is a Fragment?

A fragment is a modular section of an Activity, which has its own lifecycle. It can be added or removed while an Activity is running and can also be reused in different activities.

Background: To create a Fragment you have to subclass the Fragment class. You have to provide a public no-argument constructor, because Android will often re-instantiate a Fragment class when needed (-> state restore).

2) What is the difference between fragments & activities. Explain the relationship between the two.

An Activity is an application component that provides a screen, with which users can interact in order to do something whereas a Fragment represents a behavior or a portion of user interface in an Activity (with its own lifecycle and input events, and which can be added or removed at will).

3) When should you use a fragment rather than an activity?

  • When there are ui components that are going to be used across multiple activities.
  • When there are multiple views that can be displayed side by side (viewPager tabs)
  • When you have data that needs to be persisted across Activity restarts (such as retained fragments)

4) Why is it recommended to use only the default constructor to create a Fragment?

The reason why you should be passing parameters through bundle is because when the system restores a fragment (e.g on config change), it will automatically restore your bundle. This way you are guaranteed to restore the state of the fragment correctly to the same state the fragment was initialised with.

In Android, UI is representing as an Activity. Single Screen in an application represents as Activity while Fragments are reusable UI with business logic. Activity is a collection of Screen. In android application, Fragments are using in Navigation Drawer in our entire screen. You can also use fragment to display Google Map on screen.

Following are important points about a fragment:

  •         The fragment life cycle is closely related to the lifecycle of its host activity.
  •         A fragment can implement a behaviour that has no user interface component.
  •         A fragment has its own layout and its own behaviour with its own lifecycle 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.
  •         When the activity is paused, all the fragments available in the activity will also be stopped

6) Is it possible to use or add a fragment without using a user interface?

Yes, it is possible to do that, such as when you want to create a background behavior for a particular activity. You can do this by using add(Fragment,string) method to add a fragment from the activity

Why is it recommended to use only the default constructor to create a FragmentStackOverflow

How do you supply construction arguments into a Fragment?

A) Bundle, via Fragment.setArguments(Bundle) and retrieved via Fragment.getArguments(Bundle)

How do you supply construction arguments into a Fragment?

In order to communicate from host activity to fragment, construction arguments are passed via Bundle. Setarguments(Bundle) is used to supply construction arguments for a fragment. Getarguments() is used to retrieve the arguments supplied to setarguments(bundle).

What are two ways to add a Fragment to an Activity?

A Fragment can be declared inside the Activity’s layout file.

@Override
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.MyFragment"
            android:id="@+id/my_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
</FrameLayout>

Background:

The Android system inserts the View object returned by the Fragment’s onCreateView method directly in place of the <fragment> element.

Otherwise, a fragment can programmatically added at runtime. You can add, remove or replace a Fragment during runtime by using the APIs from FragmentTransaction.

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

ExampleFragment newFragment = new ExampleFragment();
fragmentTransaction.replace(R.id.my_fragment_container, newFragment);
fragmentTransaction.addToBackStack(null);

fragmentTransaction.commit();

“my_fragment_container” specifies a ViewGroup resource in which to place the Fragment.

DOES FRAGMENTS NEED A PARAMETERLESS CONSTRUCTOR? WHY?

Yes. The instantiate method in the Fragment class calls the newInstance method. Upon intantiation it checks that the accessor is public and that that class loader allows access it Thisallows the FragmentManager to kill and recreate Fragments with states. (The Android subsystem does similar things with Activities).

Life Cycle: 

1) Describe fragment lifecycle

  • onAttach() : The fragment instance is associated with an activity instance.The fragment and the activity is not fully initialized. Typically you get in this method a reference to the activity which uses the fragment for further initialization work.
  • onCreate() : The system calls this method when creating the fragment. You should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
  • onCreateView() : The system calls this callback when it’s time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View component from this method that is the root of your fragment’s layout. You can return null if the fragment does not provide a UI.
  • onActivityCreated() : The onActivityCreated() is called after the onCreateView() method when the host activity is created. Activity and fragment instance have been created as well as the view hierarchy of the activity. At this point, view can be accessed with the findViewById() method. example. In this method you can instantiate objects which require a Context object
  • onStart() : The onStart() method is called once the fragment gets visible.
  • onResume() : Fragment becomes active.
  • onPause() : The system calls this method as the first indication that the user is leaving the fragment. This is usually where you should commit any changes that should be persisted beyond the current user session.
  • onStop() : Fragment going to be stopped by calling onStop()
  • onDestroyView() : Fragment view will destroy after call this method
  • onDestroy() :called to do final clean up of the fragment’s state but Not guaranteed to be called by the Android platform.

2) Which method is called only once in a fragment lifecycle?

Ans. onCreate() method is fired only once during the life cycle.


Fragment lifecycle during Fragment transaction


FragmentTransaction and BackStack

1) Difference between adding/replacing fragment in backstack?

  • replace removes the existing fragment and adds a new fragment. This means when you press back button the fragment that got replaced will be created with its onCreateView being invoked.
  • add retains the existing fragments and adds a new fragment that means existing fragment will be active and they wont be in ‘paused’ state hence when a back button is pressed onCreateView is not called for the existing fragment(the fragment which was there before new fragment was added).
  • In terms of fragment’s life cycle events onPause, onResume, onCreateView and other life cycle events will be invoked in case of replace but they wont be invoked in case of add.

2) You’re replacing one Fragment with another — how do you ensure that the user can return to the previous Fragment, by pressing the Back button?

We need to save each Fragment transaction to the backstack, by calling addToBackStack() before you commit() that transaction

Android OS provides back stack function for Activity, it also provides back stack function for Fragment. If you add one Fragment into the back stack, when you press the android device back menu, you can find the Fragment that is saved in back stack popup. Until all saved Fragments in back stack popup, then the activity will exit.

We have to create  “FragmentTransaction objects on the back stack and when the user presses the Back button, the “FragmentManager pops the most recent transaction off the back stack and performs the reverse action.

As mentioned in below code:

getSupportFragmentManager().beginTransaction()
                          .add(detailFragment, "detail")
                          // Add this transaction to the back stack
                          .addToBackStack(null)
                          .commit();

3) Callbacks invoked during addition of a fragment to back stack and while popping back from back stack:

addOnBackStackChangedListener is called when fragment is added or removed from the backstack. Checkout this link for reference.

You are replacing a Fragment with another. How can you ensure that the user can return to the previous fragment by pressing the Back button?

  1. You have to add the call addToBackStack() inside the FragmentTransaction.
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.replace(R.id.my_fragment_container, fragment);
fragmentTransaction.commit();
  1. You have to override onBackPressed() in the main Activity class:
@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0) {
        getFragmentManager().popBackStack(); // reverses the last transaction
    } else {
        super.onBackPressed(); // returns to the previous Activity
    }
}

Important: If you do not call addToBackStack() inside the FragmentTransaction that removes a Fragment, then that Fragment is destroyed when the transaction is committed and the user cannot navigate back to it.

However, if you call addToBackStack() when removing a Fragment, then the Fragment is stopped and will be resumed if the user goes back. The “removed” Fragment remains in created state and only its view is destroyed.

How to programmatically add fragment to an existing ViewGroup?

1
2
3
4
5
6
7
8
9
10
11
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
 
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
 
// Commit the transaction
transaction.commit();
Reference
http://developer.android.com/guide/components/fragments.html#Adding

Fragments Communication:

1 How would you communicate between two Fragments? Android Official

If you want to send data from fragment to another Fragment we need to use an interface. Intents are only usable for sending data on an Activity level. To pass data between fragments we need to create our own interfaces.

Fragment 1 -> MainActivity -> FragmentInterFace-> Fragment 2

In onAttach() lifecycle method , the fragment implement the Interface logic and it will call Interface methods to communicate with an activity.

@Override
   public void onAttach(Context context) {
       super.onAttach(context);
       if (context instanceof OnFragmentInteractionListener) {
           mListener = (OnFragmentInteractionListener) context;
       } else {
           throw new RuntimeException(context.toString()
                   + " must implement OnFragmentInteractionListener");
       }
   }

The activity that hosts fragment must implement the interface For receiving callback events from Fragment class. First host activity creates an instance of fragment using findFragmentById method then it can deliver a message to fragment directly by calling the fragment's public methods.

 CAN YOU THINK OF HOW TO COMMUNICATE TWO FRAGMENTS?

There are many different ways we can use to communicate two different fragments in

Android, but a very useful one could be the following.

Suppose we have an Activity that is hosting two different Fragments, and

the Fragment A wants to send some information to the Fragment B.

Our Activity will implement an interface defined in the Fragment A that defines a

method “ sendInformation() ”. The interface can be called in the Fragment A, and

the Activity will receive the event. Then the Activity will implement in the method

“ sendInformation() ” how the second Fragment will handle this information.

This is a very open discussion and there are a lot of possible

answers. A more experienced developer could talk about Event

Driven Programming or Reactive Programming

Retained Fragments:

1) What are retained fragments?

By default, Fragments are destroyed and recreated along with their parent Activity’s when a configuration change occurs. Calling setRetainInstance(true) allows us to bypass this destroy-and-recreate cycle, signaling the system to retain the current instance of the fragment when the activity is recreated.

What is  retained Fragment?  AndroidDesignPatterns

FragmentPagerAdapter and FragmentStatePagerAdapter: 

1) Difference between FragmentPagerAdapter vs FragmentStatePagerAdapter?

  • FragmentPagerAdapter: the fragment of each page the user visits will be stored in memory, although the view will be destroyed. So when the page is visible again, the view will be recreated but the fragment instance is not recreated. This can result in a significant amount of memory being used. FragmentPagerAdapter should be used when we need to store the whole fragment in memory. FragmentPagerAdapter calls detach(Fragment) on the transaction instead of remove(Fragment).
  • FragmentStatePagerAdapter: the fragment instance is destroyed when it is not visible to the User, except the saved state of the fragment. This results in using only a small amount of Memory and can be useful for handling larger data sets. Should be used when we have to use dynamic fragments, like fragments with widgets, as their data could be stored in the savedInstanceState.Also it won’t affect the performance even if there are large number of fragments

The main difference between FragmentPagerAdapter and FragmentStatePagerAdapter is FragmentPagerAdapter stores the whole fragment in memory, and If we used a large amount of Fragment in ViewPager it will increase memory while FragmentStatePagerAdapter only stores the savedInstanceState of fragments, and destroys all the fragments when they lose focus.

FragmentPagerAdapter stores the previous data which is fetched from the adapter while FragmentStatePagerAdapter takes the new value from the adapter every time it is executed. Let's take an example of  Book Reader application here. I will use FragmentStatePagerAdapter and if I am creating an application which will store heavy data, then I will use FragmentPagerAdapter

What does a ViewPager?

A ViewPager is a layout manager that allows users to flip left and right through pages (typically Fragments) of data.

Background: FragmentPagerAdapter and FragmentStatePagerAdapter are two subclasses of ViewPager:

  • FragmentPagerAdapter:
    • good for a fixed or small number of pages (Fragments)
    • it never removes a Fragment instance once it’s created. It only detaches the View from the Fragment (-> onDestroyView())
  • FragmentStatePagerAdapter:
    • good for large or unknown number of pages (Fragments)
    • it completely removes Fragment instances once they are out of reach (configurable value)




______

How does the system store the Fragment state?

The system calls the onSaveInstanceState() method and stores the instance state in a collection of key-value pairs.

Important: You always have to call the superclass implementation of onSaveInstanceState(). The default implementation saves the state of the view hierarchy. This requires that each view has an unique ID (android:id).

How can a Fragment recover its previous state?

By restoring the instance state either in onCreate(), onCreateView() or onActivityCreated().

What does the Fragment’s method setRetainInstance(boolean)?

  1. setRetainInstance(true): The Fragment’s state will be retained (and not destroyed!) across configuration changes (e.g. screen rotate). The state will be retained even if the configuration change causes the “parent” Activity to be destroyed. However, the view of the Fragment gets destroyed!

    Lifecycle Calls:
    onPause() -> onStop() -> onDestroyView() -> onDetach()
    onAttach() -> onCreateView() -> onStart() -> onResume()

  2. setRetainInstance(false): The Fragment’s state will not be retained across configuration changes (default).

    Lifecycle Calls:
    onPause() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach()
    onAttach() -> onCreate() -> onCreateView() -> onStart() -> onResume()

Important: setRetainInstance(true) does not work with fragments on the back stack. setRetainInstance(true) is especially useful for long running operations inside Fragments which do not care about configuration changes.


Comments

Popular posts from this blog

Jetpack Compose based Android interview and questions

Null safety based Kotlin interview questions and answers

CustomView based Android interview questions and answers