OnClickListener de Fragment appelé après onDestroyView

J'ai un problème où ListFragment.onListItemClick est appelé après onDestroyView . Je reçois beaucoup de rapports d'erreur sur le terrain (10 à 20 par jour de ~ 1000 utilisateurs actifs), mais la seule façon de reproduire l'image consiste à marteler le bouton arrière en cliquant sur l'écran. Des centaines d'utilisateurs font-ils vraiment cela? C'est la trace:

 java.lang.IllegalStateException: Content view not yet created at au.com.example.activity.ListFragment.ensureList(ListFragment.java:860) at au.com.example.activity.ListFragment.getListView(ListFragment.java:695) at au.com.example.activity.MyFragment.onListItemClick(MyFragment.java:1290) at au.com.example.activity.ListFragment$2.onItemClick(ListFragment.java:90) at android.widget.AdapterView.performItemClick(AdapterView.java:301) at android.widget.AbsListView.performItemClick(AbsListView.java:1519) at android.widget.AbsListView$PerformClick.run(AbsListView.java:3278) at android.widget.AbsListView$1.run(AbsListView.java:4327) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5293) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) at dalvik.system.NativeStart.main(Native Method) 

Causé d'appeler getListView().getItemAtPosition dans MyFragment.onListItemClick (MyFragment: 1290). Comment getView retourne-t-il null pendant le rappel d'un gestionnaire de clics? J'ai également déterminé que le fragment était détaché à ce stade, est ajouté () était faux, et getActivity était nul.

  • GridView inside Expandable list dans Android
  • Comment passer la chaîne html à la visualisation sur Android
  • Comment obtenir l'adresse IP du réseau cellulaire lorsque le périphérique est connecté à WiFi dans Android
  • Réinitialisation de la valeur du widget de recherche (SearchView)
  • Modification automatique des emulateurs Android
  • Copie et collage d'Android sur n'importe quel champ de texte dans n'importe quelle application
  • Une solution de contournement consisterait à remplacer getListView par la listView passée à partir du public void onListItemClick(ListView listView, View v, int position, long id) rappel public void onListItemClick(ListView listView, View v, int position, long id) , mais d'autres fonctions devront encore mettre à jour d'autres parties de l'interface utilisateur, donc cela Déplacer le problème ailleurs. Au lieu de cela, j'ai annulé le rappel dans onDestroyView :

     public void onDestroyView() { mHandler.removeCallbacks(mRequestFocus); if(mList!=null){ mList.setOnItemClickListener(null); } mList = null; mListShown = false; mEmptyView = mProgressContainer = mListContainer = null; mStandardEmptyView = null; super.onDestroyView(); } 

    Mais j'ai encore ce problème onClick dans d'autres fragments (non listés) aussi. Comment le cadre supprime-t-il normalement ces rappels normalement lorsque le fragment est supprimé (p. onBackPressed -> popBackStackImmediate() )? Dans onDestroyView , je supprime les vues supplémentaires que j'ai créées sur onCreateView . Dois-je effacer manuellement tous les auditeurs que j'ai définis comme ça?

    Il s'agit d'un problème similaire à la q sans réponse: le getView () de Fragment renvoie null dans un rappel de OnClickListener

    J'utilise setOnRetainInstance(true) dans mes fragments, btw.

  • Comment puis-je déverrouiller l'écran de manière programmée dans Android?
  • Android permet le chargement multiple de fichiers (Max 150 Mo) vers le serveur PHP
  • Créer une animation de numérisation en utilisant un studio Android
  • Puis-je ouvrir la disposition du tiroir avec une animation par programme?
  • Android Studio AVD Manager ne peut pas mettre à jour les images du système
  • Données de prévisualisation de 60 / 120fps sur un appareil Android?
  • 3 Solutions collect form web for “OnClickListener de Fragment appelé après onDestroyView”

    Vous n'avez vraiment pas donné beaucoup d'informations, mais en fonction de ce que vous avez donné, cela ressemble à un fragment en attente Transactions pourrait être votre problème.

    Dans Android, chaque fois que vous changez, ou créez des fragments, tout cela se fait via Transactions en attente, à moins d'avis contraire. C'est essentiellement une condition de course.

     getSupportFragmentManager().beginTransaction() .replace(R.id.container, new ExampleFragment() .commit(); 

    L'UI Thread a une file d'attente de travail qu'il doit faire à tout moment. Même si vous avez engagé FragmentTransaction après avoir exécuté le code ci-dessus, il est effectivement mis en file d'attente sur le thread UI à la fin de la file d'attente, après que tout ce qui est actuellement en attente a été terminé. Ce que cela signifie, c'est que si les événements de clic se produisent pendant que la transaction est en attente (ce qui peut se produire facilement, c'est-à-dire que vous cliquez sur l'écran ou cliquez avec plusieurs doigts), ces événements de clic seront placés dans la file d'attente des threads d'interface après le FragmentTransaction.

    Le résultat final est que la transaction Fragment est traitée, que votre fragment View est détruit, puis vous appelez getView() et il renvoie null.

    Vous pouvez essayer quelques éléments:

    1. getSupportFragmentManager().executePendingTransactions() Cela exécutera toutes les transactions en attente alors, et supprime l'aspect en attente

    2. Vérifiez si le Fragment isVisible() ou isAdded() ou une autre méthode de fragment 'is' vous permet d'obtenir des informations d'exécution sur l'état actuel dans lequel le Fragment est dans son cycle de vie, avant d'exécuter le code qui pourrait être exécuté après la La vue fragmentée est détruite (c'est-à-dire cliquez sur les auditeurs)

    3. Donc, disons que vous avez un gestionnaire de clics, où lorsque l'utilisateur clique sur quelque chose que vous animez à un autre fragment. Vous pouvez utiliser quelque chose comme le code ci-dessous que vous exécutez avant la FragmentTransaction sur votre vue extérieure (dans un fragment, ce serait ce qui revient à partir de getView() ) et cela désactiverait définitivement les clics sur une vue si c'était Va être détruit, ou désactiver temporairement les clics pendant une période de temps si vous souhaitez réutiliser la vue.

    J'espère que cela t'aides.


     public class ClickUtil { /** * Disables any clicks inside the given given view. * * @param view The view to iterate over and disable all clicks. */ public static void disable(View view) { disable(view, null); } /** * Disables any clicks inside the given given view for a certain amount of time. * * @param view The view to iterate over and disable all clicks. * @param millis The number of millis to disable clicks for. */ public static void disable(View view, Long millis) { final List<View> clickableViews = (millis == null) ? null : new ArrayList<View>(); disableRecursive(view, clickableViews); if (millis != null) { MainThread.handler().postDelayed(new Runnable() { @Override public void run() { for (View v : clickableViews) { v.setClickable(true); } } }, millis); } } private static void disableRecursive(View view, List<View> clickableViews) { if (view.isClickable()) { view.setClickable(false); if (clickableViews != null) clickableViews.add(view); } if (view instanceof ViewGroup) { ViewGroup vg = (ViewGroup) view; for (int i = 0; i < vg.getChildCount(); i++) { disableRecursive(vg.getChildAt(i), clickableViews); } } } } 

    Parier mon bras, c'est en raison de fragments extra sans état qui vivent quelque part dans votre application. Je découragerais personnellement la conservation de l'instance et je laisse Android faire ce qu'elle peut avec elle, alors que vous utilisez un mécanisme standard pour conserver votre état (saveInstanceState, base de données, classes / patterns de haut niveau, SharedPreferences, etc.).

    Personnellement, j'ai eu beaucoup de problèmes lors de la conservation d'une instance de fragment (normalement lors de la recréation ou de la réactivation de fragments à travers les modifications de configuration ou en quittant et en rentrant dans l'application), résultant généralement de deux fragments, l'un connecté à des vues, Apatride, donc inutile; Et le "réel" gardant l'état précédent sans aucune connexion aux vues, aboutissant ainsi à des exceptions et à toutes sortes de fanciness que vous ne voulez pas avoir.

    Commencez par ne pas retenir l'instance et voir ce qui se présente.

    Vous pouvez utiliser mHandler.removeCallbacksAndMessages (null) dans plusieurs situations pour moi.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.