Remplacement de fragments et de changement d'orientation
Je suis le développement d'une application Android sur 2.x et 3.0 périphériques et donc je suis en utilisant la compatibilité de l'API. Je suis en essais sur Android 2.0.
Je suis en train de remplacer une affiche fragment avec un autre (un formulaire de recherche avec les résultats de la recherche) et je suis en train de vivre un crash lors du changement d'orientation lorsque la seconde (résultats) fragment est affiché.
En gros, j'ai une activité, qui comprend un fragment défini dans le schéma xml comme
<fragment class="org.prevoz.android.search.SearchFormFragment"
android:id = "@+id/search_form_fragment"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent" />
Le premier fragment (SearchFormFragment) est affichée en tant que par défaut. Lorsque l'utilisateur appuie sur un bouton "recherche", j'ai remplacer le SearchFormFragment avec SearchResultsFragment, qui dirige un AsyncTask (c'est pourquoi je veux le conserver) avec
//Show the search results fragment
SearchResultsFragment newSearch = new SearchResultsFragment(from, to, when);
newSearch.setRetainInstance(true);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
transaction.replace(R.id.search_form_fragment, newSearch);
transaction.addToBackStack(null);
transaction.commit();
Toutefois, lorsque le SearchFormFragment est affiché et de l'orientation est changé, mon application se bloque avec
ERROR/AndroidRuntime(334): FATAL EXCEPTION: main
ERROR/AndroidRuntime(334): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.prevoz.android/org.prevoz.android.search.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
ERROR/AndroidRuntime(334): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
ERROR/AndroidRuntime(334): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
ERROR/AndroidRuntime(334): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815)
ERROR/AndroidRuntime(334): at android.app.ActivityThread.access$2400(ActivityThread.java:125)
ERROR/AndroidRuntime(334): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
ERROR/AndroidRuntime(334): at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(334): at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(334): at android.app.ActivityThread.main(ActivityThread.java:4627)
ERROR/AndroidRuntime(334): at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(334): at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(334): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
ERROR/AndroidRuntime(334): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
ERROR/AndroidRuntime(334): at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(334): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
ERROR/AndroidRuntime(334): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582)
ERROR/AndroidRuntime(334): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
ERROR/AndroidRuntime(334): at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
ERROR/AndroidRuntime(334): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
ERROR/AndroidRuntime(334): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
ERROR/AndroidRuntime(334): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
ERROR/AndroidRuntime(334): at android.app.Activity.setContentView(Activity.java:1647)
ERROR/AndroidRuntime(334): at org.prevoz.android.search.MainActivity.onCreate(MainActivity.java:40)
ERROR/AndroidRuntime(334): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(334): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
ERROR/AndroidRuntime(334): ... 12 more
ERROR/AndroidRuntime(334): Caused by: java.lang.IllegalStateException: Fragment org.prevoz.android.search.SearchFormFragment did not create a view.
ERROR/AndroidRuntime(334): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:281)
ERROR/AndroidRuntime(334): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558)
ERROR/AndroidRuntime(334): ... 21 more
WARN/ActivityManager(59): Force finishing activity org.prevoz.android/.search.MainActivity
Pertinentes onCreateView code de SearchFormFragment est appelé et j'ai de retour valide vue:
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState)
{
View newView = inflater.inflate(R.layout.search_form_frag, container, false);
return newView;
}
Le crash se produit uniquement si la SearchResultsFragment est indiqué, le changement fonctionne bien si le défaut SearchFormFragment est affiché.
Alors, comment dois-je conserver le deuxième fragment de l'état à travers le changement d'orientation? La documentation sur les API et les changements d'état de manque vraiment.
Vous devez vous connecter pour publier un commentaire.
De ne pas créer la
SearchFormFragment
en XML. Au lieu d'avoir un videFrameLayout
qui vous renseignent dansActivity.onCreate()
sans l'ajouter à la pile de retour. De cette façon, leActivity
va garder leFragment
au lieu d'essayer d'ajouter celui spécifié dans le format XML.Également, à l'aide de
AsyncLoader
peut-être une meilleure approche, voir http://code.google.com/p/android/issues/detail?id=14944Après avoir lutté avec pendant de nombreuses heures, j'ai finalement obtenu.
Le problème n'est pas dans la configuration ou de la manière que nous appelons Fragment de classe à tous. Il a à voir avec un mauvais message affiché sur l'écran. Si vous avez un chèque pour un récipient étant la valeur null dans votre onCreateView() dans votre Ftagment classe, vous obtiendrez que des "impossible de gonfler fragment de message", au lieu de conteneur est null message. Donc, ne pas vérifier la valeur null conteneur dans votre onCreateView(). Donc, assurez-vous que votre onCreateView() ressemble à ceci:
et NON comme ceci:
Inflator.inflate
avec le conteneur fourni dansonCreateView()
, le parent est ajouté automatiquement après l'achèvement de laonCreateView()
. Vous devriez plutôt que de gonfler en passantnull
que le conteneur.container
, alors?false
signifie que vous n'avez pas à joindre les gonflés vue du conteneur, et que le conteneur est passé de sorte que le droitLayoutParam
s est utilisé pour le gonflés vue.null
ne pas gonfler correctement à son conteneur?De référence raisons: Nous avons été en mesure de résoudre un problème très similaire par l'ajout d'une
android:id
à notre fragment créé en XML.Cette condition très importante pour le soutien des accidents de la rotation libre est seulement mentionné comme une note dans la documentation: