Ich möchte meiner Anwendung eine einfache Snackbar hinzufügen, aber ich habe einen Fehler erhalten, den ich nicht herausfinden konnte, warum.
Ich habe diesen Code in die onCreateView () - Methode in meinem Fragment eingefügt.
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Und diesen Fehler erhalten:
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)
...
Wenn Ihr Fragment zu einer vorhandenen Aktivität hinzugefügt wird (Denken Sie daran, dass Sie es über XML hinzufügen können), sollten Sie die SnackBar-Methode in der onActivityCreated () -Methode des Fragments aufrufen.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
1.bewegen Sie es zur onActivityCreated-Methode.
2. Versuchen Sie, getView () in der make-Methode wie folgt zu verwenden:
Snackbar.make(getView(), "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
In einer Codebasis, an der ich gerade arbeitete, wurden in asynchronen Methodenrückrufen Snackbar
s angezeigt, z. B. Fehlerbehandlungsroutinen eines Netzwerkaufrufs. Bei der Erstellung der Snackbar
wurde die Fragment
nicht mehr angehängt, und ihre View
, die von getView()
zurückgegeben wurde, hatte keine CoordinatorLayout
oder FrameLayout
Snackbar
in der Ansichtshierarchie.
Insbesondere die private findSuitableParent()
-Methode in Snackbar
durchläuft die Hierarchie:
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;
}
Das Ergebnis dieser Methode wird an den Konstruktor Snackbar
übergeben, der die Funktion getContext()
aufruft. Wenn diese Methode null
zurückgibt, wird die NPE wie in der Frage angezeigt angezeigt.
Es gibt mehrere Möglichkeiten, das Problem zu beheben, vorausgesetzt, der glückliche Fall, dass eine CoordinatorLayout
oder FrameLayout
in angehängten Fragmenten vorhanden ist, gilt weiterhin:
Stellen Sie sicher, dass Ihr Fragment nicht getrennt ist, indem Sie zuerst isDetached()
überprüfen.
Was ich am Ende selbst getan habe: Es gab bereits einen Builder-Pattern Styling-Wrapper für die Snackbar
in der Codebase. Daher gab ich im Builder die findSuitableParent()
und fügte ein Häkchen hinzu, um zu sehen, dass es != null
zurückgibt, bevor ich Snackbar.make()
aufrief. Auf diese Weise mussten die Aufrufer des Snackbar-Builders keine zusätzlichen Überprüfungen hinzufügen.
Im Prozess sucht die Snackbar nach der Ansicht.
Die App selbst weiß also zur Laufzeit nicht wirklich, dass Sie sich tatsächlich auf die Ansicht des Fragments bezogen haben.
Platziere deine Snackbar-Show-Methode im "onResume" des Fragments. Hoffe, das hilft.
Warum machen Sie das innerhalb von onCreate?
Stellen Sie außerdem sicher, dass Sie einige Regeln beachten:
In der Dokumentation heißt es: "Snackbar versucht, eine übergeordnete Ansicht zu finden, um die Ansicht von Snackbar von dem für die Ansicht angegebenen Wert zu halten".
Sie können also jede Ansicht weitergeben, die im Moment angehängt ist.