webentwicklung-frage-antwort-db.com.de

Android Snackbar NullPointerException in Fragment

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)
...
14
Murat Erdogan

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();
}
19

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();
12
Michael

In einer Codebasis, an der ich gerade arbeitete, wurden in asynchronen Methodenrückrufen Snackbars 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 FrameLayoutSnackbar 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:

  1. Stellen Sie sicher, dass Ihr Fragment nicht getrennt ist, indem Sie zuerst isDetached() überprüfen.

  2. 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.

3
laalto

Im Prozess sucht die Snackbar nach der Ansicht. 

  • Sie haben die Fragmentansicht verwendet
  • Die Fragmentansicht selbst ist jedoch noch nicht angehängt, da onAttach des Fragments noch nicht aufgerufen wird.

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.

2
gorbos

Warum machen Sie das innerhalb von onCreate?

Stellen Sie außerdem sicher, dass Sie einige Regeln beachten:

  1. Stellen Sie sicher, dass Ihre Hauptaktivität von AppCompatActivity erbt, da dies für die Verwendung der Support-Bibliotheken erforderlich ist.
  2. Stellen Sie sicher, dass die Ansicht, die Sie übergeben, tatsächlich vorhanden ist (deshalb frage ich, warum Sie dies in onCreate ausführen und warum nicht danach?)
1
AkiAki007

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.

0
Daniel Arroyo