Android SnackBar 在与设计支持库 23.0.0 接触时崩溃
Android SnackBar crashes on touch with design support library 23.0.0
升级到设计支持库 23.0.0 并构建 SDK 23 后,当我尝试关闭 Snackbar
:
时,我的应用程序崩溃了
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.MotionEvent.getAction()' on a null object reference
at android.support.design.widget.AppBarLayout$Behavior.onInterceptTouchEvent(AppBarLayout.java:729)
at android.support.design.widget.AppBarLayout$Behavior.onInterceptTouchEvent(AppBarLayout.java:629)
at android.support.design.widget.CoordinatorLayout.performIntercept(CoordinatorLayout.java:357)
at android.support.design.widget.CoordinatorLayout.onInterceptTouchEvent(CoordinatorLayout.java:409)
自更新以来我没有改变任何东西,我使用我知道的唯一方式来显示 Snackbar:
Snackbar.make(rootView, getString(R.string.error_no_permissions),Snackbar.LENGTH_LONG).show();
在 CoordinatorLayout
上报告了一个 NPE 问题,可能与此相关:CoordinatorLayout NullPointerException in onTouchEvent but I still can't find a workaround for my situation. I've tried this possible solution 但仍然没有成功...
编辑:
原来解决方案是(正如@NikolaDespotoski 所建议的那样)覆盖默认 AppBarLayout.Behavior
public class AppBarLayoutBehavior extends AppBarLayout.Behavior {
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child,
MotionEvent ev) {
return !(parent != null && child != null && ev != null) || super
.onInterceptTouchEvent(parent, child, ev);
}
}
...并在我们的 AppBarLayout
中使用它
((CoordinatorLayout.LayoutParams) findViewById(R.id.appbar).getLayoutParams())
.setBehavior(new AppBarLayoutBehavior());
目前的另一个修复是覆盖 AppBarLayout.Behavior
的 onInterceptTouchEvent
并丢弃无效或空值 MotionEvent
,只是为了减轻超级实现中的崩溃。
这听起来像:
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev){
return ev != null ? super.onInterceptTouchEvent(parent,child, ev) : true;
}
对于可能无效的MotionEvent
,我们不会做任何处理,所以我们让继承的Behavior
认为我们已经处理了它。
此问题似乎已在 Android 支持库 23.0.1(2015 年 9 月)
中得到解决
我通过将 SnackBar 的视图设置为引用我的 content_main.[= 来解决这个问题(在支持库 24 alpha 和 Android N 预览中) 47=]的布局ViewGroup而不是我的activity_main.xml布局ViewGroup(CoordinatorLayout).
将 content_main 的布局设置为 FrameLayout 或 CoordinatorLayout 时发生了同样的事情。
(Android 带有 FAB 的 Activity Studio 模板使用 android.support.design.widget.CoordinatorLayout 作为 Activity_Main 中的布局并提供第二个 xml 文件,content_main,以便您将视图等放入 content_main 中的第二个布局(通常)。)
如果您在触摸 it/move 时遇到 Snackbar 崩溃的问题,您可以尝试将传递给 Snackbar.make(layoutViewName...) 的视图更改为最内层的布局(或其他视图)并查看是否可以解决问题。
不幸的是,这导致 activity_main 中的 FAB 在 SnackBar 出现时没有像它应该的那样向上移动。
我不得不恢复到 23.2.1 和 API23。那时不需要解决方法。然后我可以引用 activity_main 的 CoordinatorLayout 作为 SnackBar.make(view...) 中的第一个参数 FAB 按预期向上移动并且滑动 SnackBar 不会导致崩溃.
编辑:23.3.0 及更高版本也应该没问题。我提到恢复到(当时)23.2.1 的目的是要注意它不能在 24 alpha 中工作,而是在 23.x 稳定版本中工作。
升级到设计支持库 23.0.0 并构建 SDK 23 后,当我尝试关闭 Snackbar
:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.MotionEvent.getAction()' on a null object reference
at android.support.design.widget.AppBarLayout$Behavior.onInterceptTouchEvent(AppBarLayout.java:729)
at android.support.design.widget.AppBarLayout$Behavior.onInterceptTouchEvent(AppBarLayout.java:629)
at android.support.design.widget.CoordinatorLayout.performIntercept(CoordinatorLayout.java:357)
at android.support.design.widget.CoordinatorLayout.onInterceptTouchEvent(CoordinatorLayout.java:409)
自更新以来我没有改变任何东西,我使用我知道的唯一方式来显示 Snackbar:
Snackbar.make(rootView, getString(R.string.error_no_permissions),Snackbar.LENGTH_LONG).show();
在 CoordinatorLayout
上报告了一个 NPE 问题,可能与此相关:CoordinatorLayout NullPointerException in onTouchEvent but I still can't find a workaround for my situation. I've tried this possible solution 但仍然没有成功...
编辑:
原来解决方案是(正如@NikolaDespotoski 所建议的那样)覆盖默认 AppBarLayout.Behavior
public class AppBarLayoutBehavior extends AppBarLayout.Behavior {
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child,
MotionEvent ev) {
return !(parent != null && child != null && ev != null) || super
.onInterceptTouchEvent(parent, child, ev);
}
}
...并在我们的 AppBarLayout
((CoordinatorLayout.LayoutParams) findViewById(R.id.appbar).getLayoutParams())
.setBehavior(new AppBarLayoutBehavior());
目前的另一个修复是覆盖 AppBarLayout.Behavior
的 onInterceptTouchEvent
并丢弃无效或空值 MotionEvent
,只是为了减轻超级实现中的崩溃。
这听起来像:
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev){
return ev != null ? super.onInterceptTouchEvent(parent,child, ev) : true;
}
对于可能无效的MotionEvent
,我们不会做任何处理,所以我们让继承的Behavior
认为我们已经处理了它。
此问题似乎已在 Android 支持库 23.0.1(2015 年 9 月)
中得到解决我通过将 SnackBar 的视图设置为引用我的 content_main.[= 来解决这个问题(在支持库 24 alpha 和 Android N 预览中) 47=]的布局ViewGroup而不是我的activity_main.xml布局ViewGroup(CoordinatorLayout).
将 content_main 的布局设置为 FrameLayout 或 CoordinatorLayout 时发生了同样的事情。
(Android 带有 FAB 的 Activity Studio 模板使用 android.support.design.widget.CoordinatorLayout 作为 Activity_Main 中的布局并提供第二个 xml 文件,content_main,以便您将视图等放入 content_main 中的第二个布局(通常)。)
如果您在触摸 it/move 时遇到 Snackbar 崩溃的问题,您可以尝试将传递给 Snackbar.make(layoutViewName...) 的视图更改为最内层的布局(或其他视图)并查看是否可以解决问题。
不幸的是,这导致 activity_main 中的 FAB 在 SnackBar 出现时没有像它应该的那样向上移动。
我不得不恢复到 23.2.1 和 API23。那时不需要解决方法。然后我可以引用 activity_main 的 CoordinatorLayout 作为 SnackBar.make(view...) 中的第一个参数 FAB 按预期向上移动并且滑动 SnackBar 不会导致崩溃.
编辑:23.3.0 及更高版本也应该没问题。我提到恢复到(当时)23.2.1 的目的是要注意它不能在 24 alpha 中工作,而是在 23.x 稳定版本中工作。