IllegalStateException lors du remplacement d’un fragment

C’est une petite application de test Android 2.2 utilisant le package de compatibilité. C’est la façon (incorrecte, bien sûr) d’essayer de remplacer un fragment lors de la réception d’un clic. J’essaie de le remplacer par une nouvelle instance (différente) de la même classe Fragment. Comme je l’expliquerai, cela ne fonctionne pas comme prévu et j’ai besoin d’aide:

public class MainFragmentActivity extends FragmentActivity { ... public void myAction(View view) { ... RightFragment newRightFrag = RightFragment.newInstance(myNewOption); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); ft.replace(R.id.landscape_right_fragment, newRightFrag); ft.commit(); } } 

Vous aurez sûrement vu quelle est mon erreur. Quoi qu’il en soit, donnons un peu plus d’explications sur ce que l’application devrait faire:

Orientation paysage :

 --------- ---------- | L | R | -> click -> | L | R2 | --------- ---------- 

En orientation paysage, l’activité a une vue avec 2 fragments: ” leftLand ” et ” rightLand “, et si vous cliquez sur un bouton du fragment ” leftLand “, cela crée un nouveau fragment et remplace l’instance de fragment ” rightLand ” par un autre. instance de la même classe FragamentActivity. Ce qui rend différentes ces deux instances est un paramètre passé à “newInstance (int)”, basé sur le bouton cliqué.

Orientation du portrait:

 ----- ----- | | | | | L | -> click -> | R | | | | | ----- ----- 

En orientation portrait, il montre juste le fragment ” leftPort ” (a la même disposition que ” leftLand “) et si vous cliquez sur son bouton, il lance un Intention et lance RightFragmentActivity, qui montre le fragment ” rightLand

Ca marche bien … si je ne remplace pas le bon fragment. Si je le fais (en cliquant sur le bouton en orientation paysage), lors d’un changement d’orientation ultérieur (redémarrage de l’activité), FragmentActivity ne peut pas démarrer à cause d’un ” IllegalStateException: Fragment RightFragment did not create a view :

 D/AndroidRuntime( 1428): Shutting down VM W/dalvikvm( 1428): threadid=1: thread exiting with uncaught exception (group=0x4001d800) E/AndroidRuntime( 1428): FATAL EXCEPTION: main E/AndroidRuntime( 1428): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.agm.test/com.agm.test.MainFragmentActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment E/AndroidRuntime( 1428): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) E/AndroidRuntime( 1428): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) E/AndroidRuntime( 1428): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815) E/AndroidRuntime( 1428): at android.app.ActivityThread.access$2400(ActivityThread.java:125) E/AndroidRuntime( 1428): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037) E/AndroidRuntime( 1428): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime( 1428): at android.os.Looper.loop(Looper.java:123) E/AndroidRuntime( 1428): at android.app.ActivityThread.main(ActivityThread.java:4627) E/AndroidRuntime( 1428): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime( 1428): at java.lang.reflect.Method.invoke(Method.java:521) E/AndroidRuntime( 1428): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) E/AndroidRuntime( 1428): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) E/AndroidRuntime( 1428): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime( 1428): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment E/AndroidRuntime( 1428): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582) E/AndroidRuntime( 1428): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) E/AndroidRuntime( 1428): at android.view.LayoutInflater.inflate(LayoutInflater.java:407) E/AndroidRuntime( 1428): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) E/AndroidRuntime( 1428): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) E/AndroidRuntime( 1428): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198) E/AndroidRuntime( 1428): at android.app.Activity.setContentView(Activity.java:1647) E/AndroidRuntime( 1428): at com.agm.test.MainFragmentActivity.onCreate(MainFragmentActivity.java:25) E/AndroidRuntime( 1428): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) E/AndroidRuntime( 1428): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) E/AndroidRuntime( 1428): ... 12 more E/AndroidRuntime( 1428): Caused by: java.lang.IllegalStateException: Fragment com.agm.test.RightFragment did not create a view. E/AndroidRuntime( 1428): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:287) E/AndroidRuntime( 1428): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558) E/AndroidRuntime( 1428): ... 21 more W/ActivityManager( 59): Force finishing activity com.agm.test/.MainFragmentActivity 

J’ai réalisé que l’ancien ” RightFragment ” n’est pas détruit après avoir été remplacé. C’est probablement une conséquence de ma mauvaise façon d’essayer de la remplacer.

Toute aide sera grandement appréciée.

Merci d’avance!

/ Angel Galindo Muñoz

Je pense que vous avez peut-être mal compris mon commentaire, alors je vais vous donner une explication plus détaillée ici.

Un problème fréquemment rencontré lors de la suppression ou du remplacement de fragments consiste à supprimer un fragment qui a été ajouté à la mise en page via XML plutôt que par programmation en Java. Ce n’est pas la même chose que de gonfler la propre disposition du fragment dans la fonction onCreateView() du code Java du fragment (c’est ce que vous semblez décrire dans votre réponse à mon commentaire). Pour illustrer ce dont je parle, je vais vous montrer deux façons dont les gens essaient de supprimer / remplacer des fragments.

C’est la mauvaise façon de le faire:

Mise en page XML:

    

Java:

 swapFragment() { Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); transaction.commit(); } 

Ce code ne s’exécutera pas comme prévu. Le fragment initial ajouté dans la présentation XML ne sera pas supprimé. Cela est dû au fait que les mises en page XML sont destinées à décrire des éléments de mise en page statiques. Vous pouvez modifier leur contenu au moment de l’exécution ou les masquer, mais vous ne pouvez pas supprimer ces éléments de la présentation. C’est ce que Dianne Hackborn disait dans le fil de discussion auquel j’ai déjà eu access.

C’est la bonne façon de le faire (au moins dans mon expérience):

Mise en page XML:

    

Java:

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_layout); ExampleFragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.add(R.id.fragment_container, newFragment); transaction.commit(); } 

 swapFragment() { Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); transaction.commit(); } 

Cette stratégie n’ajoute pas le fragment dans la mise en page initiale. Au lieu de cela, il l’ajoute dans le code Java lors de la création de l’activité. Cela lui permet d’être supprimé de la mise en page (soit en utilisant remove() ou replace() )

Cela ne résoudra peut-être pas votre problème, mais Fragments crée une difficulté commune. Vous pouvez vous assurer que vous ajoutez les Fragments de manière appropriée pour permettre leur suppression, et si cela ne résout pas le problème, nous pourrons continuer à les résoudre.

il y a une autre façon, lorsque vous développez des applications pour tablette avec de grands écrans, vous pouvez gonfler différentes dispositions pour chaque orientation d’écran. Il vous suffit de créer les deux dispositions et de les nommer en portrait ou en paysage. l’orientation.

sur l’événement onClick, identifiez simplement l’orientation avec: getResources (). getConfiguration (). orientation

et fais tes affaires