Showing posts with label Fragments. Show all posts
Showing posts with label Fragments. Show all posts

Tuesday, May 6, 2014

Fragment lifecycle with respect to its Activity

What is Fragment?

Fragment represents a behavior or a portion of user interface in an ActivityWe can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. 

The Fragment class has code that looks a lot like an Activity. It contains callback methods similar to an activity, such as onCreate()onStart()onPause(), andonStop(). In fact, if you're converting an existing Android application to use fragments, you might simply move code from your activity's callback methods into the respective callback methods of your fragment.

Fragment Lifecycle

Origin : http://developer.android.com/guide/components/fragments.html#Lifecycle

Fragment lifecycle with respect to its Activity

Fragment's lifecycle is tied to its owning activity and the normal flow of fragment in a activity.

1.    MainActivity onCreate
     Fragment onAttach
     Fragment onCreate
     Fragment onCreateView
     Fragment onViewCreated
     Fragment onActivityCreated
2.    MainActivity onStart
          Fragment onStart
3.    MainActivity onResume
          Fragment onResume
          Fragment onStop
4.    MainActivity onStop
          Fragment onDestroyView
          Fragment onDestroy
          Fragment onDetach
5.    MainActivity onDestroy

What happens? If we navigates to another activity from fragment and come back to main activity?

Here we have two scenarios, where fragment life cycle works.
1.    Activity is not destroyed when user leaves it.
2.    Activity got destroyed when user leaves it.
Activity Normal flow
Activity got destroyed
MainActivity onCreate
          Fragment onAttach
          Fragment onCreate
          Fragment onCreateView
          Fragment onViewCreated
          Fragment onActivityCreated
MainActivity onStart
          Fragment onStart
MainActivity onResume
          Fragment onResume
MainActivity onCreate
          Fragment onAttach
          Fragment onCreate
          Fragment onCreateView
          Fragment onViewCreated
          Fragment onActivityCreated
MainActivity onStart
          Fragment onStart
MainActivity onResume
          Fragment onResume
          Fragment onStop
MainActivity onStop
          Fragment onStop
MainActivity onStop
          Fragment onDestroyView
          Fragment onDestroy
          Fragment onDetach
MainActivity onDestroy
MainActivity onRestart
MainActivity onStart
          Fragment onStart
MainActivity onResume
          Fragment onResume
          Fragment onAttach
          Fragment onCreate
MainActivity onCreate
          Fragment onCreateView
          Fragment onViewCreated
          Fragment onActivityCreated
MainActivity onStart
          Fragment onStart
MainActivity onResume
          Fragment onResume

In the above differentiation, the 2nd and 3rd row tells the flow of life cycle of fragment with respect to its activity.
By this flow change, we should be aware in writing our business logics.

Why, we should be aware?

Example: Assume, we have a custom action bar header, we are modifying the header depend upon the fragment selection in the fragment.
The custom header is called in the MainActivity Oncreate method as follows
         ActionBar bar = getActionBar();
        if (bar != null) {
bar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO);
          bar.setCustomView(R.layout.custom_header);
        }

        // enable ActionBar app icon to behave as action to toggle nav drawer
        bar.setDisplayHomeAsUpEnabled(true);
        bar.setHomeButtonEnabled(true);

In fragment, the custom header is updated as follows.
Create instance of the activity in fragment to update the action bar header.
onAttach(Activity)called once the fragment is associated with its activity. So, we can assign our variable inside the onAttach
public MainActivity activity;
@Override
public void onAttach(Activity activity) {
          Log.d("CHECK", " Fragment onAttach");
      super.onAttach(activity);
      this.activity = (MainActivity) activity;
}

activity.updateActionBarHeader(activity.getTitle().toString());
Usually, we will be setting headers in onCreate of activity or fragment, Since onCreate(Bundle)called to do initial creation of the fragment.
Application launches and works fine, when we placed the updateActionBarHeader in onCreate, but when application navigated from fragment and returns back, the application crashes if the activity is destroyed and the exception thrown as follows.
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo {PACKAGE_NAME/MainActivity}: java.lang.NullPointerException
          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
          at android.app.ActivityThread.access$600(ActivityThread.java:130)
          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
          at android.os.Handler.dispatchMessage(Handler.java:99)
          at android.os.Looper.loop(Looper.java:137)
          at android.app.ActivityThread.main(ActivityThread.java:4745)
          at java.lang.reflect.Method.invokeNative(Native Method)
          at java.lang.reflect.Method.invoke(Method.java:511)
          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
          at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
          at MainActivity.updateActionBarHeader(MainActivity.java:232)
          at MainActivity$PlanetFragment.onCreate(MainActivity.java:276)
          at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:796)
          at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
          at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1017)
          at android.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1797)
          at android.app.Activity.onCreate(Activity.java:886)
          at MainActivity.onCreate(MainActivity.java:80)
          at android.app.Activity.performCreate(Activity.java:5008)
          at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
          ... 11 more

So, don't try to put the logic of updating action bar in onCreateView rather than onCreate of fragment and avoid the crash.

Thanks for reading :) 
Whether this post is helpful?

Have something to add to this post? If you have any other quick thoughts/hints that you think people will find useful? Share it in the comments.

Friday, September 20, 2013

Android: ExpandableListView using CursorTreeAdapter with in fragment, Content Provider, LoaderCallbacks and CursorLoader



Sample application using Single-pane and Multi-pane Layouts with ExpandableListView using CursorTreeAdapter with in fragment, Content Provider, LoaderCallbacks & CursorLoader.

MULTI-PANE LAYOUTS
On a tablet, you want to take advantage of all the space. Get rid of line lengths that stretch the whole screen. Multi-pane layouts allow you to resolve than. Panes should represent content in an ordered manner; from left-to-right... content becomes more detailed.

Rule is to maintain functional parity in all screen orientations. We have a few strategies to solve this. You can use all or some. You can either: stretch, stack, expand/collapse, or show/ hide different UI panes, depending on the screen orientation. Some figures demonstrate these designs.

Implementation should be done with Fragments. A fragment is "a fragment of an activity". It's a unit that can be reused across activities. It's something smaller than an activity that shares lifecycle patterns, but is focused on a sub-layout that's separated in your codebase.


Ref: AndroidUIs





Figure: Implementing Android UI's for Handset and Tablets
 


On a tablet-sized screen, the Activity A layout contains both Fragment A and Fragment B.
On a handset-sized screen, the Activity A layout contains only Fragment A (the list view). In order to show the details in Fragment B, Activity B must open.

In Expandable List, Child Query is fetched from CursorLoader, We may get doubt, Why we should go for Cursor Loader and what are their adv.?

A CursorLoader automatically re-runs the query when data associated with the query changes. It runs an asynchronous query in the background against a ContentProvider, and returns the results to the Activity or FragmentActivity from which it was called. This allows the Activity or FragmentActivity to continue to interact with the user while the query is ongoing.

Loading Data in the Background

Querying a ContentProvider for data you want to display takes time. If you run the query directly from an Activity, it may get blocked and cause the system to issue an "Application Not Responding" message. Even if it doesn't, users will see an annoying delay in the UI. To avoid these problems, you should initiate a query on a separate thread, wait for it to finish, and then display the results.
You can do this in a straightforward way by using an object that runs a query asynchronously in the background and reconnects to your Activity when it's finished. This object is aCursorLoader. Besides doing the initial background query, aCursorLoader automatically re-runs the query when data associated with the query changes.
This class describes how to use a CursorLoader to run a background query. Examples in this class use the v4 Support Library versions of classes, which support platforms starting with Android 1.6.

Running a Query with a CursorLoader

A CursorLoader runs an asynchronous query in the background against a ContentProvider, and returns the results to the Activity or FragmentActivity from which it was called.

Source Code: Here

Thanks for reading :)
If you have any other quick thoughts/hints that you think people will find useful, feel free to leave a comment.