Ich habe mir das EU4You-Beispielprojekt in Der Leitfaden für den Busy-Coder zur Android-Entwicklung 4.2 (mit freundlicher Genehmigung von Mark Murphy aka commonsware hier auf StackOverflow). Es mag einfacher sein, diesem Beispielprojekt zu folgen, aber ich werde versuchen, relevante Teile des Codes in der Frage zu veröffentlichen. Sie müssen das Projekt ActionBarSherlock ebenfalls importieren. Sie müssen den Java-Compiler auch auf 1.6 setzen (um die Annotation @Override zu ermöglichen).
HINWEIS: Ich habe die min-sdk auf 8 (2.3, Froyo) und die Ziel-sdk auf 16 (4.1, Ice Cream Sandwich) geändert.
Hinweis: Ich habe die countries
frame-Layout-ID in left_pane
und die details
frame-Layout-ID in right_pane
geändert.
Hauptlayoutdatei (layout-large-land):
%Vor%Hauptlayoutdatei:
%Vor%Die ursprüngliche Version der Beispielanwendung hat zwei Aktivitäten (SherlockFragmentActivities um genau zu sein).
Wenn Sie im Listenfragment auf ein Land klicken, überprüft EU4You (die Haupthostaktivität) das Vorhandensein und die Sichtbarkeit von DetailsFragment. Wenn es existiert, lädt es die Landeswebsite innerhalb dieses Fragments. Ist dies nicht der Fall, wird die DetailsActivity ausgelöst, die dann das DetailsFragment hinzufügt (das dann die Website für das angegebene Land lädt).
Dies funktioniert wie eine typische Anwendung, die mehrere Bildschirmlayouts auf Tablets und Mobiltelefonen unterstützt.
Mein Problem ist, dass ich die DetailsActivity entfernen und bei einer einzelnen Aktivität bleiben möchte. Ich möchte das Listenfragment mit dem Detailfragment austauschen (ersetzen), wenn ich mich nicht im großen Landschaftslayout befinde (mit anderen Worten, ich bin entweder in einem Hochformat-Layout auf einem Tablet oder auf einem Mobilteil in beliebiger Ausrichtung). Was ich getan habe, wurde in der EU4You SherlockFragmentActivity folgendermaßen geändert:
Original (mit leichter Benennungsänderung bei den im Hinweis weiter oben genannten framelayout-Namen ... Länder ist left_pane, Details sind right_pane):
%Vor%Meine modifizierte Version einzelne Aktivität :
%Vor%Dies funktioniert wie erwartet. Ich klicke auf eine Website in der Liste (im Hochformat auf einem Tablet oder auf einem Mobilteil in beliebiger Ausrichtung) und die Details werden im Detailfragment angezeigt, das das Website-Listenfragment ersetzt. Wenn ich dann aber auf die Home-Taste des Geräts klicke, während die Länderdetails angezeigt werden, bekomme ich einen Force-Close-Fehler mit den folgenden Logcat-Details (nur mit dem Standard-Layout mit nur dem einzelnen Frame-Layout). t haben dieses Problem im Querformat auf Tabletten, wenn es ein linkes_paneel und ein rechtes_paneel gibt:
%Vor%Ich kann diesen Fehler verhindern, wenn ich die folgende Zeile aus dem obigen Code entferne:
%Vor%Ich muss die Ersetzungstransaktion dem Backstack hinzufügen können, damit ich diese Zeile nicht entfernen kann (diese Beispielanwendung ist die Grundlage für meine reale Anwendung, die mehr Zeug enthält, aber ich habe sie verwendet, um mein Problem zu vereinfachen ).
Also zwei Fragen:
Beachten Sie, dass in meiner realen Anwendung diese Logik in Registerkarten einer Aktionsleiste (ActionBarSherlock, da ich auf Version 2.3 (Froyo) unterstützen muss) enthalten ist.
UPDATE (2012-Nov-22 13:27 EST)
Ich habe ein Beispielprojekt auf GitHub veröffentlicht. Ich bin neu in der Eclipse- und Android-Entwicklung, daher habe ich vielleicht nicht alles enthalten, was ich brauchte (der Arbeitsbereich wurde nicht eingeschlossen und ich glaube nicht, dass das ActionBarSherlock-Projekt enthalten ist ... es müsste importiert werden. hier )).
Ich kann Ihren spezifischen Absturz nicht kommentieren, da ich diesen Fehler nicht gesehen habe, außer zu vermuten, dass er an replace()
gebunden ist, anstatt attach()
/ detach()
zu verwenden (nur eine Schätzung).
Allerdings ist getSupportFragmentManager().executePendingTransactions();
für mich ein Code-Geruch. Ich schätze, dass Sie dies für details.loadUrl(url);
tun. Fügen Sie stattdessen ein Datenelement in DetailsFragment
hinzu, etwa wie urlToBeApplied
, und speichern Sie loadUrl()
den Wert dort, wenn WebView
noch nicht existiert. Es kann dann die URL in onCreateView()
anwenden. Ob das in Bezug auf deinen Absturz helfen wird, kann ich nicht sagen.
Möglicherweise möchten Sie ein vollständiges Beispielprojekt veröffentlichen, das das Problem veranschaulicht, da Sie darauf zählen, dass Personen die Fehlermeldung erkennen.
AKTUALISIEREN
Anhand der Beispiel-App konnte ich das Problem besser diagnostizieren.
Content view not yet created
, auf einem ListFragment
, bedeutet, dass wir getListView()
für ein Fragment aufrufen wollen, das onCreateView()
noch nicht durchlaufen hat oder has durch onDestroyView()
gegangen ist . Dies weist normalerweise auf ein Zeitproblem hin.
In diesem Fall, wie sich herausstellt, war die Arbeit, die zusammenbrach, sowieso überflüssig. onSaveInstanceState()
versucht, die Position des überprüften Artikels beizubehalten, sodass wir sie später erneut überprüfen können (z. B. nach einer Konfigurationsänderung). Allerdings müssen wir nicht einmal im aktivierten Modus sein, wenn wir auf normal
angezeigt werden. Der überprüfte Modus ist für den activated
-Zustand, der relevant ist, wenn dann Liste und Details nebeneinander liegen, ist aber irrelevant, wenn dies nicht der Fall ist. Die Problemumgehung besteht also darin, sich einfach nicht mit der onSaveInstanceState()
-Logik zu befassen, wenn wir keine dauerhafte Auswahl benötigen ... was wir leicht erreichen können, indem wir isPersistentSelection()
auf unserem listener
aufrufen.
Der Argumentation halber sollten wir jedoch so tun, als müssten wir diese Arbeit machen. In diesem Fall haben wir ein paar Optionen. Am einfachsten ist es wahrscheinlich, onDestroyView()
zu überschreiben und die Position des überprüften Artikels im Cache zu speichern, indem Sie onSaveInstanceState()
verwenden, wenn getListView()
null
zurückgibt.
Tags und Links android android-fragments commonsware