7

SaveInstanceState

For data like Integer, Long, String and else are fine, I just put it in the bundle and get it back once the onCreateView gets called again. But my fragment also has listener like following,

public class SomeFragment extends Fragment {
    public interface SomeListener {
        public void onStartDoingSomething(Object whatItIsDoing, Date when);
        public void onDoneDoingTheThing(Object whatItDid, boolean result);
    }

    private SomeFragmentListener listener;
    private String[] args;

    public static SomeFragment getInstance(SomeListener _listener, String... _args) {
        SomeFragment sf = new SomeFragment();
        sf.listener = _listener
        sf.args = _args

        return sf;
    }

    // rest of the class

    // the example of where do I invoke the listener are
    // - onSetVisibilityHint
    // - When AsyncTask is done
    // - successfully download JSON
    // etc.
} 

How can I have the listener to bundle so that I can get it back later?

Aditya
  • 2,876
  • 4
  • 34
  • 30
Tar_Tw45
  • 3,122
  • 6
  • 35
  • 58
  • 1
    why would you want to do that, what is the reason of holding a listener object?? – Akhil Jain Jan 10 '14 at 11:32
  • This fragment is been using in several places by activities. Each activity react to this call back differently so I think it's a suitable design pattern, do you have any other pattern recommend? – Tar_Tw45 Jan 11 '14 at 11:50
  • 1
    ok if its a listener ,I am guessing its an interface and for each activity where you want listener, you could implement listener in that class and define functionality separate for each activity. – Akhil Jain Jan 11 '14 at 11:55
  • But, then, this lead back to my original question, how can I save the state or the referencing between listener and delegate? – Tar_Tw45 Jan 11 '14 at 14:29
  • 1
    you to not to need to keep listener, it will be registered when activity is recreated, implementing a listener makes it a part of activity/class – Akhil Jain Jan 11 '14 at 14:42

2 Answers2

8

I recently just found the proper way to do this and I want to share for future reader of this topic.

The proper way to save listener of the fragment is not to save it, but instead, request from activity when fragment got attached to activity.

public class TheFragment extends Fragment {
    private TheFragmentListener listener;

    @Override
    public void onAttach(Context context) {
        if (context instanceof TheFragmentContainer) {
            listener = ((TheFragmentContainer) context).onRequestListener();
        }
    }

    public void theMethod() {
        // do some task
        if (listener != null) {
            listener.onSomethingHappen();
        }
    }

    public interface TheFragmentContainer {
        public TheFragmentListener onRequestListener();
    }

    public interface TheFragmentListener {
        public void onSomethingHappen();
    }
}
  • when the fragment attach to an activity, we check if activity implement TheFragmentContainer or not
  • if the activity does, request listener from activity.
Tar_Tw45
  • 3,122
  • 6
  • 35
  • 58
  • 1
    This is a great answer and really helped me think out my situation in particular. I kept trying to set the listener of the fragment on the parent Activity's onCreate, but rotation made it problematic. Reading this answer made me ponder my approach and, with a lil rewriting, resulted in a much better solution. Thanks! – welshk91 Oct 02 '16 at 06:38
  • 3
    `onAttach(Activity activity)` is now deprecated. The new method signature is `onAttach(Context context)`. Any ideas how to solve this now? – 最白目 Mar 03 '17 at 08:15
  • you can get the activity by getActivity() method in the fragment and do the same things as above. I know it's too late, but this is for future readers – akxer Feb 15 '18 at 05:17
  • I'm here a lot of years later but I found another solution. You can re create the fragment from the fragment's parent activity if savedInstanceState != null. – Nico May 16 '18 at 23:22
1

Any Classes without a suitable .put method in Bundle need to implement Serializable (as do any objects used within) or implement Parcelable (the latter is preferred). You can then use the putParcelable or putSerializable methods on Bundle.

NigelK
  • 8,255
  • 2
  • 30
  • 28