2014-01-10 6 views
5

SaveInstanceStateSave-Schnittstelle (Listener) in onSaveInstanceState

Für Daten wie Integer, Long, String und ist sonst in Ordnung, ich es nur im Bündel legen und es zurück, sobald die onCreateView wieder aufgerufen werden. Aber mein Fragment hat auch Zuhörer wie folgende,

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. 
} 

Wie kann ich den Hörer zu bündeln, so dass ich es später wiederbekommen kann?

+1

Warum möchten Sie das tun, was ist der Grund für das Halten eines Listener-Objekts? –

+0

Dieses Fragment wird an verschiedenen Orten nach Aktivitäten verwendet. Jede Aktivität reagiert auf diesen Rückruf anders, daher denke ich, dass es sich um ein passendes Designmuster handelt. Hast du ein anderes Muster empfohlen? –

+1

ok, wenn es ein Listener ist, nehme ich an, es ist eine Schnittstelle und für jede Aktivität, wo Sie Listener wollen, könnten Sie Listener in dieser Klasse implementieren und Funktionen für jede Aktivität separat definieren. –

Antwort

4

Ich habe vor kurzem gerade den richtigen Weg gefunden, dies zu tun, und ich möchte für zukünftige Leser dieses Themas teilen.

Die richtige Methode, Listener des Fragments zu speichern, besteht nicht darin, es zu speichern, sondern stattdessen von der Aktivität anzufordern, wenn das Fragment an die Aktivität angehängt wurde.

public class TheFragment extends Fragment { 
    private TheFragmentListener listener; 

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

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

    public interface TheFragmentContainer { 
     public TheFragmentListener onRequestListener(); 
    } 

    public interface TheFragmentListener { 
     public void onSomethingHappen(); 
    } 
} 
  • , wenn das Fragment einer Aktivität anhängen, überprüfen wir, ob Aktivität TheFragmentContainer implementieren oder nicht
  • , wenn die Aktivität der Fall ist, Anforderung Zuhörer von Aktivität.
+1

Dies ist eine großartige Antwort und hat mir wirklich geholfen, über meine Situation nachzudenken. Ich habe versucht, den Listener des Fragments auf die onCreate der übergeordneten Aktivität zu setzen, aber die Rotation hat es problematisch gemacht. Das Lesen dieser Antwort ließ mich über meinen Ansatz nachdenken und führte mit einer kurzen Überarbeitung zu einer viel besseren Lösung. Vielen Dank! – welshk91

+1

danke, speicherte meinen Hintern :) – Karoly

+2

'onAttach (Aktivität Aktivität)' ist jetzt veraltet. Die neue Methodensignatur ist 'onAttach (Context context)'. Irgendwelche Ideen, wie man das jetzt löst? – dan

1

Alle Klassen ohne eine geeignete .put-Methode in Bundle müssen Serializable implementieren (wie alle darin verwendeten Objekte) oder Parcelable implementieren (letzteres wird bevorzugt). Sie können dann die putParcelable-Methode oder die putSerializable-Methode für Bundle verwenden.

Verwandte Themen