2016-08-12 2 views
0

Also habe ich ein Fragment, das an eine Aktivität angehängt ist, und ich versuche sicherzustellen, dass die Dinge reibungslos laufen, wenn der Bildschirm gedreht wird (oder irgendetwas, das die Aktivität unterbrechen würde)). Um dies zu tun, verwende ich die Methoden onSaveInstanceState und onRestoreInstanceState in meiner Aktivität, um die Informationen zu speichern, die meine Aktivität speichert.onCreateView() für Fragment, das vor Aktivität aufgerufen wird onRestoreInstanceState()

Wenn die Ansicht für mein Fragment erzeugt wird, fragt das Fragment, das die Aktivität zur Information (Diese ist in onCreateView() für das Fragment):

ArrayList<String> picList = mListener.getPics(); 
ArrayList<String> descripList = mListener.getDescriptions(); 

für das Fragment Um es, die Ansicht zu erstellen benötigt Zugriff auf picList und descripList, die Mitgliedsvariablen für die Aktivität sind. Diese Membervariablen werden in onSaveInstanceState und onRestoreInstanceState gespeichert und wiederhergestellt.

protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    if(photoFile != null) 
     outState.putString("photoFile", photoFile.getAbsolutePath()); 
    outState.putString("currentFragTag", currentFragTag); 
    outState.putStringArrayList("picList", picList); 
    outState.putStringArrayList("descripList", descripList); 
} 

@Override 
protected void onRestoreInstanceState(Bundle saved) { 
    super.onRestoreInstanceState(saved); 
    if(saved.getString("photoFile") != null) 
     photoFile = new File(saved.getString("photoFile")); 
    currentFragTag = saved.getString("currentFragTag"); 
    picList = saved.getStringArrayList("picList"); 
    descripList = saved.getStringArrayList("descripList"); 
    currentFrag = getFragmentManager().findFragmentByTag(currentFragTag); 
    changeFrag(currentFrag, currentFragTag); 
} 

Das Problem ist, onCreateView() vor onRestoreInstanceState aufgerufen wird() in der Aktivität wird, genannt. Ich habe versucht, stattdessen onActivityCreated() im Fragment zu verwenden, aber das wurde auch zuvor onRestoreInstanceState() aufgerufen. Mit einem angehängten Debugger wird onRestoreInstanceState() beim Drehen des Bildschirms immer zuletzt aufgerufen. Dies bedeutet, dass das Fragment beim Erstellen der Ansicht keinen Zugriff auf die Informationen der Aktivität hat.

Soll das passieren? Wie kann ich in der Ansicht meines Fragments Informationen aus der Aktivität verwenden, wenn die Aktivität wiederhergestellt wird?

+0

Haben Sie das Fragment auf 'setRetainInstance (true)' gesetzt? –

+0

Ich habe nicht. Was würde das zur Folge haben? Ich habe eine schnelle Suche durchgeführt und festgestellt, dass ich sie nicht für Fragmente auf dem Backstack verwenden kann, was problematisch wäre. – TLF

+1

Sie müssen diese Methode einfach auf die Fragment-Instanz aufrufen, wenn Sie sie erstellen. Ich bin mir nicht ganz sicher, was es tut, aber es ist eine Möglichkeit, den Zustand eines Fragments beizubehalten. Vielleicht könntest du dich hier beziehen? http://stackoverflow.com/questions/15313598/once-for-all-how-to-correctly-save-instance-state-of-fragments-in-backstack –

Antwort

1

Aktualisiert Antwort:

Lesen Sie die Alternativen Passing data between a fragment and its container activity. Siehe auch this.

Zurück Antwort überarbeitet:

this sehen und versuchen, Ihren Code in onResume() zu platzieren und die Ansicht oder detach/attach the fragment als eine schnelle Lösung ungültig ist aber nicht the best solution wie Alex Lockwood sagte:

Fragmente sind wiederverwendbare UI-Komponenten. Sie haben ihren eigenen Lebenszyklus, zeigen ihre eigene Ansicht an und definieren ihr eigenes Verhalten. Normalerweise brauchen Sie Ihre Aktivität nicht mit den internen Funktionen eines Fragments zu tun, da das Verhalten des Fragments unabhängig und unabhängig von einer bestimmten Aktivität sein sollte.

Wenn Sie wirklich den Code, bevor benötigen, um die nächsten Methoden außer Kraft setzen und direkt die erforderlichen Daten in dem Fragmente Speicher/Wiederherstellen:

/** 
* Called when the fragment's activity has been created and this 
* fragment's view hierarchy instantiated. It can be used to do final 
* initialization once these pieces are in place, such as retrieving 
* views or restoring state. It is also useful for fragments that use 
* {@link #setRetainInstance(boolean)} to retain their instance, 
* as this callback tells the fragment when it is fully associated with 
* the new activity instance. This is called after {@link #onCreateView} 
* and before {@link #onViewStateRestored(Bundle)}. 
* 
* @param savedInstanceState If the fragment is being re-created from 
* a previous saved state, this is the state. 
*/ 
@Override 
public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    if (savedInstanceState != null) { 
     restoreInstanceState(savedInstanceState); 
    } 
} 

/** 
* Called to ask the fragment to save its current dynamic state, so it 
* can later be reconstructed in a new instance of its process is 
* restarted. If a new instance of the fragment later needs to be 
* created, the data you place in the Bundle here will be available 
* in the Bundle given to {@link #onCreate(Bundle)}, 
* {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}, and 
* {@link #onActivityCreated(Bundle)}. 
* 
* <p>This corresponds to {@link Activity#onSaveInstanceState(Bundle) 
* Activity.onSaveInstanceState(Bundle)} and most of the discussion there 
* applies here as well. Note however: <em>this method may be called 
* at any time before {@link #onDestroy()}</em>. There are many situations 
* where a fragment may be mostly torn down (such as when placed on the 
* back stack with no UI showing), but its state will not be saved until 
* its owning activity actually needs to save its state. 
* 
* @param outState Bundle in which to place your saved state. 
*/ 
@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    outState.put...; 
} 

und diese erstellen, verwendet, um die benötigten Daten aus Bündel abrufen :

public void restoreInstanceState(Bundle savedInstanceState) { 
    ... = savedInstanceState.get... 
} 

oder getActivity() Methode verwenden, um direkt zu einem gewissen Methode oder ein Feld den Zugriff auf von hier, wenn Sie den Code auf Ihrer Aktivität aus irgendeinem Grund brauchen.

/** 
* Return the {@link FragmentActivity} this fragment is currently associated with. 
* May return {@code null} if the fragment is associated with a {@link Context} 
* instead. 
*/ 
final public FragmentActivity getActivity() { 
    return mHost == null ? null : (FragmentActivity) mHost.getActivity(); 
} 

Zum Beispiel: ((YourActivity) getActivity()).getPics();

Und die getPics() Methode zur Aktivität hinzufügen.

Weitere Informationen here und eine alternative Lösung zur Definition einer Schnittstelle here.

+0

können Sie die Ansicht des Fragments in onResume bearbeiten() Da ich mit onResume() getestet habe und ich auf Informationen aus der Aktivität zugreifen konnte, enthält meine Methode folgende Zeilen: descrip.setText (descripList.get (i)); img.setImageBitmap (Bitmap); Die Ansicht ändert sich jedoch nicht – TLF

+0

Sie können die Ansicht ungültig machen oder das Fragment trennen/anhängen, aber ich denke, dass es besser gestaltete Alternativen gibt, lesen Sie diese http://stackoverflow.com/questions/12705342/refreshing-a-view-inside-a -Fragment. – albodelu

1

Ich denke, der einfachste Weg ist die Verwendung von EventBus.
Sie können eine "msg" senden, wenn Ihre Aktivität neu erstellt wird, und die "Zielmethode" Ihres Fragments erhält diese Nachricht (die msg ist Objekt, es kann ein Bündel sein).

+1

BTW, @ Ardocks Antwort ist großartig. –

Verwandte Themen