Android Snackbar NullPointerException в фрагменте

Я хочу добавить базовую закусочную в мое приложение, но я получил сообщение об ошибке, которое я не мог понять, почему.

Я добавил этот код в метод onCreateView () в своем фрагменте.

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

И получил эту ошибку:

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

Если ваш фрагмент добавлен к существующей активности (помните, вы можете добавить его через xml), вы должны вызвать метод SnackBar в методе onActivityCreated () фрагмента.

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

1. Переместите его в метод onActivityCreated.

2.Попробуйте использовать getView () в make как:

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

В кодовой базе, над которой я работал, были Snackbar s в асинхронных обратных Snackbar метода, таких как обработчики ошибок сетевого вызова. Когда была сделана Snackbar , Fragment он собирался уйти, больше не привязан, и его View возвращенный getView() , не имел CoordinatorLayout или FrameLayout Snackbar хочет иметь в иерархии представления.

В частности, это частный findSuitableParent() в Snackbar который пересекает иерархию:

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

Результат этого метода передается конструктору Snackbar который вызывает на нем getContext() , и если этот метод возвращает null вы получаете NPE, как показано в вопросе.

Есть несколько способов устранить проблему, предполагая, что счастливый случай наличия CoordinatorLayout или FrameLayout в прикрепленных фрагментах сохраняется:

  1. Убедитесь, что ваш фрагмент не отсоединен, isDetached() проверив isDetached() .

  2. То, что я закончил тем, что сделал сам: уже существовала оболочка шаблона шаблона Builder для Snackbar в базе кода, поэтому я findSuitableParent() в построителе и добавил чек, чтобы увидеть, что он возвращает != null Snackbar.make() прежде чем пытаться вызвать Snackbar.make() . Таким образом, вызывающим абонентам Snackbar не нужно было добавлять дополнительные проверки.

По ходу процесса снэк-бар ищет представление.

  • Вы использовали представление фрагментов
  • Но сам фрагмент не привязан, так как onAttach фрагмента еще не вызван.

Поэтому само приложение не знает, во время выполнения, что вы на самом деле ссылаетесь на представление фрагмента.

Попробуйте разместить свой метод snackbar show на «onResume» фрагмента. Надеюсь это поможет.

Почему вы делаете это в onCreate?

Кроме того, убедитесь, что вы выполняете несколько правил:

  1. Убедитесь, что ваша основная активность наследуется от AppCompatActivity, что необходимо для использования файлов поддержки.
  2. Убедитесь, что представление, которое вы передаете, фактически существует (вот почему я спрашиваю, почему вы делаете это в onCreate и почему не после?)

Как говорится в документации, «Snackbar попытается найти родительское представление, чтобы удерживать представление Snackbar от значения, данного для просмотра».

Таким образом, вы можете передать любое представление, которое прилагается в данный момент.

Intereting Posts
JSONObject Not Serializable? Как распространять файлы apk для моих друзей? Как позвонить в андроид? Почему я не могу загрузить AVD из Eclipse с 1024 МБ ОЗУ? Обфускация в проектах Xamarin Переключение между действиями в android? Проблема сборки Gradle: обновление Quickblox и httpclient на последних Android SDK23 Android RatingBar имеет «плохой» порог для определенных устройств, исправить? Android – ImageView, отображающий изображение из галереи в «пейзаже» Поддержание стандартного приложения Состояние состояния Back Back для Android в Android (с использованием режима запуска SingleTask) Android – как изменить горизонтальный цвет индикатора выполнения без потери анимации «Не удалось выполнить повторную установку из-за разных подписей приложений» – возможно ли переопределить? Что случилось с этим методом вычисления inSampleSize для растровых изображений? Недостаточно памяти Локальные значки в меню «Настройки Android» растягиваются, чтобы заполнить пункт меню, неясное название AsyncTask execute () или executeOnExecutor ()?