Android 片段中的 Snackbar NullPointerException
Android Snackbar NullPointerException in Fragment
我想在我的应用程序中添加一个基本的小吃店,但我收到了一个我无法弄清楚原因的错误。
我在 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)
...
为什么要在 onCreate 中执行此操作?
此外,请确保您遵守几条规则:
- 确保您的主要 Activity 继承自 AppCompatActivity,因为这是使用支持库所必需的。
- 确保你传递的视图确实存在(这就是为什么我要问你为什么在 onCreate 中这样做,为什么不在之后?)
如果你的Fragment是添加到现有的activity(记住你可以通过xml添加它),你应该将SnackBar的方法调用到Fragment的onActivityCreated()方法中。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
1.move 它到 onActivityCreated 方法。
2.try 在 make 方法中使用 getView(),如下所示:
Snackbar.make(getView(), "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
按流程,小吃店搜索视图。
- 您使用了片段视图
- 但是片段视图本身还没有附加,因为 onAttach 的
尚未调用片段。
所以应用程序本身并不知道,在运行时,你实际上指的是片段的视图。
尝试将您的 snackbar show 方法放在片段的 "onResume" 处。
希望这有帮助。
如文档所述"Snackbar will try and find a parent view to hold Snackbar's view from the value given to view"。
因此您可以传递当前附加的任何视图。
在我正在处理的代码库中,异步方法回调中显示了 Snackbar
s,例如网络调用的错误处理程序。当制作 Snackbar
时,它要走的 Fragment
不再附加并且 getView()
返回的 View
没有 CoordinatorLayout
或 FrameLayout
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()
,如果此方法 returns null
您将获得 NPE,如问题。
有几种方法可以解决这个问题,假设在附加片段中有 CoordinatorLayout
或 FrameLayout
的快乐情况仍然成立:
首先检查 isDetached()
以确保您的片段未分离。
我最终自己做了什么:代码库中已经有 Snackbar
的 Builder pattern 样式包装器,所以我在构建器并在尝试调用 Snackbar.make()
之前添加了一个检查以查看它 returns != null
。这样 Snackbar 构建器调用者就不必添加任何额外的检查。
我想在我的应用程序中添加一个基本的小吃店,但我收到了一个我无法弄清楚原因的错误。
我在 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)
...
为什么要在 onCreate 中执行此操作?
此外,请确保您遵守几条规则:
- 确保您的主要 Activity 继承自 AppCompatActivity,因为这是使用支持库所必需的。
- 确保你传递的视图确实存在(这就是为什么我要问你为什么在 onCreate 中这样做,为什么不在之后?)
如果你的Fragment是添加到现有的activity(记住你可以通过xml添加它),你应该将SnackBar的方法调用到Fragment的onActivityCreated()方法中。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
1.move 它到 onActivityCreated 方法。
2.try 在 make 方法中使用 getView(),如下所示:
Snackbar.make(getView(), "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
按流程,小吃店搜索视图。
- 您使用了片段视图
- 但是片段视图本身还没有附加,因为 onAttach 的 尚未调用片段。
所以应用程序本身并不知道,在运行时,你实际上指的是片段的视图。
尝试将您的 snackbar show 方法放在片段的 "onResume" 处。 希望这有帮助。
如文档所述"Snackbar will try and find a parent view to hold Snackbar's view from the value given to view"。
因此您可以传递当前附加的任何视图。
在我正在处理的代码库中,异步方法回调中显示了 Snackbar
s,例如网络调用的错误处理程序。当制作 Snackbar
时,它要走的 Fragment
不再附加并且 getView()
返回的 View
没有 CoordinatorLayout
或 FrameLayout
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()
,如果此方法 returns null
您将获得 NPE,如问题。
有几种方法可以解决这个问题,假设在附加片段中有 CoordinatorLayout
或 FrameLayout
的快乐情况仍然成立:
首先检查
isDetached()
以确保您的片段未分离。我最终自己做了什么:代码库中已经有
Snackbar
的 Builder pattern 样式包装器,所以我在构建器并在尝试调用Snackbar.make()
之前添加了一个检查以查看它 returns!= null
。这样 Snackbar 构建器调用者就不必添加任何额外的检查。