片段中的Android Snackbar NullPointerException

Posted

技术标签:

【中文标题】片段中的Android Snackbar NullPointerException【英文标题】:Android Snackbar NullPointerException in Fragment 【发布时间】:2015-08-14 16:31:43 【问题描述】:

我想在我的应用程序中添加一个基本的快餐栏,但我收到了一个我不知道原因的错误。

我在 Fragment 的 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)
...

【问题讨论】:

试试.setAction("Action", null).show(getActivity()); http://williammora.com/snackbar-android-library/ 它没有用。顺便说一句,我正在使用 android.support.v4.app.Fragment 是否意味着此错误。 在 logcat 中可以清楚地看到 SnackBar 需要 Context @MD 如果有官方库,则无需使用 GitHub 库(当然,除非它不适合您的应用程序)。 @Murat 也许您的 view 那时还没有初始化?从表面上看,这就是问题所在。 【参考方案1】:

如果你的Fragment被添加到现有的activity中(记住你可以通过xml添加),你应该在Fragment的onActivityCreated()方法中调用SnackBar的方法。

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

【讨论】:

或者你可以在你的片段中添加一个 CoordinatorLayout。【参考方案2】:

1.将其移至 onActivityCreated 方法。

2.尝试在 make 方法中使用 getView(),如下所示:

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

【讨论】:

也可以试试:***.com/questions/32305627/…【参考方案3】:

在我正在处理的代码库中,有Snackbars 显示在异步方法回调中,例如网络调用的错误处理程序。当Snackbar 被制作时,它要离开的Fragment 不再附加,并且getView() 返回的View 没有CoordinatorLayoutFrameLayout Snackbar 想要拥有在视图的层次结构中。

具体来说,是 Snackbar 中的私有 findSuitableParent() 方法遍历层次结构:

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。

有几种方法可以解决此问题,假设在附加片段中包含 CoordinatorLayoutFrameLayout 的快乐情况仍然成立:

    首先检查isDetached(),确保您的片段没有分离。

    我最终自己做了什么:代码库中已经有一个 Builder pattern 样式包装器用于 Snackbar,所以我在构建器中分叉了 findSuitableParent() 并添加了一个检查以查看它是否返回 @ 987654342@ 在尝试致电 Snackbar.make() 之前。这样,Snackbar 构建器调用者就不必添加任何额外的检查。

【讨论】:

【参考方案4】:

通过进程,小吃店搜索视图。

您使用了片段视图 但是片段视图本身还没有附加,因为 onAttach 的 片段尚未被调用。

因此,在运行时,应用程序本身并不真正知道您实际上指的是片段的视图。

尝试将您的snackbar show 方法放在片段的“onResume”中。 希望这会有所帮助。

【讨论】:

【参考方案5】:

为什么要在 onCreate 中这样做?

另外,请确保您遵守几条规则:

    确保您的主 Activity 继承自 AppCompatActivity,因为这是使用支持库所必需的。 确保您传递的视图确实存在(这就是为什么我要问您为什么要在 onCreate 中执行此操作,为什么不在之后执行此操作?)

【讨论】:

很好地尝试了规则 1。【参考方案6】:

正如文档中所说,“Snackbar 将尝试找到一个父视图,以根据赋予视图的值来保存 Snackbar 的视图”。

因此您可以传递当前附加的任何视图。

【讨论】:

以上是关于片段中的Android Snackbar NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

片段中的TextView在Android Studio中返回Null

Snackbar 在片段类中不起作用

getSupportFragmentManager().findFragmentById 为 android 片段中的谷歌地图返回 null?

来自另一个片段的 Snackbar 回调

android片段getArguments()返回null

Android - 如何显示包含从片段中获取的字符串的快餐栏