Je souhaite ajouter une barre de base à mon application, mais j'ai reçu une erreur indiquant que je ne pouvais pas comprendre pourquoi.
J'ai ajouté ce code dans la méthode onCreateView () de mon fragment.
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Et a reçu cette erreur:
06-01 10:26:09.955 1232-1232/? E/ActivityThread﹕ Failed to find provider info for me.muraterdogan.watchme.MetricaContentProvider
06-01 10:26:10.075 1232-1447/? E/ActivityThread﹕ Failed to find provider info for me.muraterdogan.watchme.YPLContentProvider
06-01 10:33:55.044 6646-6646/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: me.muraterdogan.watchme, PID: 6646
Java.lang.NullPointerException: Attempt to invoke virtual method 'Android.content.Context Android.view.ViewGroup.getContext()' on a null object reference
at Android.support.design.widget.Snackbar.<init>(Snackbar.Java:116)
at Android.support.design.widget.Snackbar.make(Snackbar.Java:140)
at me.muraterdogan.watchme.fragments.TrendingFragment.GetData(TrendingFragment.Java:90)
at me.muraterdogan.watchme.fragments.TrendingFragment.onCreateView(TrendingFragment.Java:83)
...
Si votre fragment est ajouté à une activité existante (n'oubliez pas que vous pouvez l'ajouter via xml), vous devez appeler la méthode de SnackBar dans la méthode onActivityCreated () du fragment.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
1. déplacez-le vers la méthode onActivityCreated.
2.try à utiliser getView () dans la méthode make comme suit:
Snackbar.make(getView(), "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Dans une base de code sur laquelle je travaillais, il y avait Snackbar
s affichés dans les rappels de méthode asynchrones tels que les gestionnaires d'erreur d'un appel réseau. Lorsque la variable Snackbar
était créée, la Fragment
qu'elle allait partir n'était plus attachée et sa View
telle que renvoyée par getView()
n'avait pas de CoordinatorLayout
ou FrameLayout
Snackbar
veut avoir dans la hiérarchie de la vue.
En particulier, c'est la méthode privée findSuitableParent()
dans Snackbar
qui traverse la hiérarchie:
private static ViewGroup findSuitableParent(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {
// We've found a CoordinatorLayout, use it
return (ViewGroup) view;
} else if (view instanceof FrameLayout) {
if (view.getId() == Android.R.id.content) {
// If we've hit the decor content view, then we didn't find a CoL in the
// hierarchy, so use it.
return (ViewGroup) view;
} else {
// It's not the content view but we'll use it as our fallback
fallback = (ViewGroup) view;
}
}
if (view != null) {
// Else, we will loop and crawl up the view hierarchy and try to find a parent
final ViewParent parent = view.getParent();
view = parent instanceof View ? (View) parent : null;
}
} while (view != null);
// If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
return fallback;
}
Le résultat de cette méthode est transmis au constructeur Snackbar
qui appelle getContext()
, et si cette méthode renvoie null
, vous obtenez le NPE comme indiqué dans la question.
Il existe deux manières de résoudre le problème, en supposant que le cas heureux de la présence d'une variable CoordinatorLayout
ou FrameLayout
dans les fragments attachés est toujours valable:
Assurez-vous que votre fragment n'est pas détaché en vérifiant d'abord isDetached()
.
Ce que j'ai fini par faire moi-même: il y avait déjà un Générateur modèle styling wrapper pour la variable Snackbar
dans la base de code, alors j’ai créé la fonction findSuitableParent()
dans le générateur et ajouté une coche pour qu’elle renvoie != null
avant de tenter d’appeler Snackbar.make()
. De cette façon, les appelants du constructeur de la barre de progression n'ont pas à ajouter de vérifications supplémentaires.
Par le processus, le snack-bar cherche la vue.
Ainsi, l'application elle-même ne sait pas vraiment, au moment de l'exécution, que vous faisiez réellement référence à la vue du fragment.
Essayez de placer votre méthode d’émission de snackbar sur le "résumé" du fragment . J'espère que cela vous aidera.
Pourquoi faites-vous cela dans onCreate?
De plus, assurez-vous de suivre quelques règles:
Comme indiqué dans la documentation, "Snackbar essaiera de trouver une vue parente pour conserver la vue de Snackbar à partir de la valeur donnée à voir".
Ainsi, vous pouvez passer n’importe quelle vue qui est attachée pour le moment.