Android Fragments, Saving State and Screen Rotation

Evelina Vrabie

Dedicated coder, occasional blogger, hackathon goer and friendly team mate.

You may also read...

  • http://www.view-unlimited.com Michael Tirkey

    Great Post. Really helped me a lot…:)
    I did had a question though:

    1) I see that after we load the items, and if the orientation changes, the items are not reloaded and it’s great. My question is that how will I make sure that the item in a specific position in the list view stays in its position. Because when the orientation changes, the items don’t load again but the item position changes and the list is displaying from scratch. Is there any way to view the item in the position it is in.

    Thank.. will really appreciate your help.

  • Rajesh

    Awesome blog… keep posting….. It solve my problem within 5 minutes…
    Thanks a lot

  • Craig

    really really helpful. Thanks.

  • Pingback: Android: AsyncTasks and Rotation | RP Discovered()

  • gingo

    One more note. In my opinion the mBtnReload property is a memory leak. When your activity gets restarted, it is still referenced through this reference to the Button. Or am I missing something?

  • gingo

    Great article. I find only one problem, try to start background process and press hardware Home button on you phone (move activity to the background). Wait 2s (or 5s for sure) and now switch back to your activity. Oh no, the ProgressDialog is still there! Any ideas, how to solve this?

  • João Rossa

    Getting the error:

    “java.lang.ClassNotFoundException: org.codeandmagic.android.MainActivity in loader dalvik.system.PathClassLoader[/data/app/org.codeandmagic.android-2.apk]”

  • http://www.facebook.com/senkethya Senkethya Sar

    Thank you all, I had met this kind of problem. After I read this post I found other one way by this sentence “That is because we need to re-connect – akainitLoader()” It sound might be crazy but it work on my work.
    I just call this.getSupportedLoaderManger(); in onCreate(final Bundle savedInstanceState).

  • Andrey Zaicev

    Thank you for post. I had a trouble with Loaders. This post helped me.

  • Alexjlockwood

    Why do you think calling “setRetainInstance(true)” is so important? The whole point of Loaders is to manage Loaders across the Activity/Fragment lifecycles. Dianne Hackborn (lead framework developer for Android) even goes as far as to suggest that you shouldn’t use “setRetainInstanceState(true)” with Loaders.

    • Evelina

      I’m not using setRetainInstance(true) for managing the Loaders state across screen flips. As you say, loaders already remember their state without me doing anything. But for all the rest of situations (e.g. remembering some saved variable contents in that fragment) you need setRetainInstance *UNLESS* your fragment is added to the backstack, in which case you don’t need to do anything else.

      • Alexjlockwood

        I just reread my comment from a couple days ago… the first sentence makes me sound like a jerk. Sorry about that haha.

        I am not sure whether or not I agree with you yet… I think I’m going to play around with the source code a bit and I’ll let you know what I think. My gut feeling is telling me that a more complete implementation would have overriden the “onStartLoading”, “onStopLoading”, etc. methods that are inherited from the Loader class. I think not implementing these methods is what is preventing the Loader from retaining its state… and if this is the case, “setRetainInstance(true)” is more of a quick fix than anything… does that make any sense? I’ll report back…

  • dave mich

    Nice one, solved my problem thanks.

  • Anonymous

    Hey, I just found your article, and it helped me out quite a bit. However, there is one issue that I ran into while doing this, that had me tearing my hair out for a while. For some reason, on my setup, my ListFragment subclass had “setShowList” to false. This caused a spinner to appear in the background, in addition to the ProgressDialog I was showing. And since I never set ShowList to true, the list would never be shown. In order to fix this, I added a “setShowList(true)” after I set the ListView’s adapter.

    • Anonymous

      Hi there,

      Take a look at this: http://developer.android.com/reference/android/app/ListFragment.html#setListShown(boolean) So the default value is true (meaning to show the list). You can use this function to display the progress loader before the data is actually loaded into the list adapter. What I usually do is: setListAdapter(myAdapter); setListShown(false) -> this will display the progress instead; then start a cursor/async loader that fetches the data needed then onLoadFinished() I call setListShown(true) to display the values and hide the preloader.

  • Paul Turchenko

    getListView().invalidateViews();

    WHY?

  • outhorand

    Thank you very much for this insight. Been having trouble for two days because on rotate screen onLoadFinished() would repeat the same items again and again. Splendid and thanks alot!

  • http://profiles.google.com/wp19831014 peng wang

    cool,thank you it save me time

  • Spamularity

    Very helpful.

    public void onLoadFinished(Loader arg0, String arg1) {
    LoaderManager lm = getLoaderManager();
    lm.destroyLoader(arg0.getId());
    }

    I had to add this to the magic section in my case or it would rerun it on every rotate.

    • Alex Lockwood

      This is definitely not a solution to the problem… in fact, this kind of goes against the whole design goals/purpose of the LoaderManager. To correctly fix the problem, you should override the Loader’s “onStartLoading”, “onStopLoading”, etc. methods. Google search “cursorloader.java source code” for a sample Loader implementation.

  • Catalin

    Nice article. Thanks. It cleared up some stuff for me.