2015-06-01 12 views
14

Desidero aggiungere uno snackbar di base alla mia applicazione, ma ho ricevuto un errore che non sono riuscito a capire perché.Android Snackbar NullPointerException in Fragment

Ho aggiunto questo codice nel metodo onCreateView() nel mio frammento.

Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG) 
      .setAction("Action", null).show(); 

E ha ricevuto questo errore:

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) 
... 
+1

prova '.setAction ("Azione", null) .show (getActivity());' –

+0

[http://williammora.com/snackbar-android-library/](http://williammora. com/snackbar-android-library /) –

+0

non ha funzionato. Dal modo in cui sto usando android.support.v4.app.Fragment se significa qualcosa per questo errore. –

risposta

19

Se il frammento si aggiunge all'attività esistente (Ricorda che puoi aggiungerlo tramite xml), dovresti chiamare il metodo di SnackBar nel metodo onActivityCreated() del Fragment.

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG) 
     .setAction("Action", null).show(); 
} 
+0

Spiacente, questo non funziona per me. –

+3

oppure puoi aggiungere un CoordinatorLayout nel tuo frammento. –

1

Perché stai facendo questo all'interno onCreate?

Inoltre assicurarsi che si sta seguendo un paio di regole:

  1. Assicurarsi che la vostra attività principale eredita da AppCompatActivity ciò è necessario per l'utilizzo delle librerie di supporto.
  2. Assicurarsi che l'opinione che si sta passando in realtà esiste (questo è il motivo per cui sto chiedendo il motivo per cui si sta facendo questo in onCreate e perché no, dopo?)
+0

bel tentativo con la regola 1. – ashubuntu

12

1.move al metodo onActivityCreated.

2.Try utilizzare GetView() nel metodo make come segue:

Snackbar.make(getView(), "Snackbar", Snackbar.LENGTH_LONG) 
     .setAction("Action", null).show(); 
+0

Prova anche: https://stackoverflow.com/questions/32305627/snackbar-is-not-working-within-fragment-class –

2

Tramite il processo, le ricerche snack bar per la visualizzazione.

  • Si usavano i frammenti vista
  • Ma la vista frammento sé non è ancora attaccato, poiché onAttach del frammento non è ancora chiamato.

Quindi l'applicazione in sé non sa, in fase di esecuzione, che si stava effettivamente riferendo alla vista del frammento.

Provare a posizionare il metodo dello snackbar sul "onResume" del frammento. Spero che questo aiuti.

0

Come dice la documentazione "Snackbar tenterà di trovare una vista genitore per mantenere la vista di Snackbar dal valore dato alla vista".

Quindi è possibile passare qualsiasi vista che è allegata al momento.

3

In un codebase su cui stavo lavorando, c'erano Snackbar s mostrati in callback di metodi asincroni come i gestori degli errori di una chiamata di rete. Quando è stato effettuato il, il numero Fragment non era più collegato e il suo numerocome restituito da getView() non aveva uno CoordinatorLayout o FrameLayoutSnackbar desiderato nella gerarchia della vista.

In particolare, è il findSuitableParent() metodo privato in Snackbar che attraversa la gerarchia:

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; 
} 

Il risultato di questo metodo viene passato al Snackbar costruttore che chiama getContext() su di esso, e se questo metodo restituisce null si ottiene l'NPE come visto nella domanda.

ci sono un paio di modi per risolvere il problema, assumendo il caso felice di avere un CoordinatorLayout o FrameLayout in frammenti allegate detiene ancora:

  1. Assicurarsi che il frammento non viene staccato controllando isDetached() prima.

  2. Quello che ho finito per fare me stesso: c'era già un wrapper Builder pattern styling per la Snackbar nella base di codice, così ho biforcato il findSuitableParent() nel generatore e aggiunto un controllo per vedere ritorna != null prima di tentare di chiamare Snackbar.make(). In questo modo i chiamanti del builder Snackbar non hanno dovuto aggiungere ulteriori controlli.