自 android 版本 3.0 起,图库 onItemClick 和 onTouchEvent 不能一起使用

Posted

技术标签:

【中文标题】自 android 版本 3.0 起,图库 onItemClick 和 onTouchEvent 不能一起使用【英文标题】:Gallery onItemClick and onTouchEvent don't work together since android version 3.0 【发布时间】:2012-01-15 07:10:47 【问题描述】:

我有一个画廊,它有一个 OnItemSelectedListener 和一个 OnItemClickListener。所以我可以在图片之间移动,如果我点击一个,就会发生其他事情(取决于我点击了哪个)。 它在 3.0 版本之前运行良好,但从那里(3.0-4.0)处理 onItemClick 事件后,发生致命异常:

12-07 18:46:03.008: E/androidRuntime(935): FATAL EXCEPTION: main
12-07 18:46:03.008: E/AndroidRuntime(935): java.lang.NullPointerException
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.GestureDetector.onTouchEvent(GestureDetector.java:587)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.widget.Gallery.onTouchEvent(Gallery.java:937)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.View.dispatchTouchEvent(View.java:5462)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1947)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1708)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1953)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1722)
12-07 18:46:03.008: E/AndroidRuntime(935):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1882)
12-07 18:46:03.008: E/AndroidRuntime(935):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1361)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
12-07 18:46:03.008: E/AndroidRuntime(935):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1830)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.View.dispatchPointerEvent(View.java:5638)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2827)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2406)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.os.Looper.loop(Looper.java:137)
12-07 18:46:03.008: E/AndroidRuntime(935):  at android.app.ActivityThread.main(ActivityThread.java:4340)
12-07 18:46:03.008: E/AndroidRuntime(935):  at java.lang.reflect.Method.invokeNative(Native Method)
12-07 18:46:03.008: E/AndroidRuntime(935):  at java.lang.reflect.Method.invoke(Method.java:511)
12-07 18:46:03.008: E/AndroidRuntime(935):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-07 18:46:03.008: E/AndroidRuntime(935):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-07 18:46:03.008: E/AndroidRuntime(935):  at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

我可以确认这个问题不仅发生在Gallery 上,也发生在ImageView 上。罪魁祸首似乎是视图内的VelocityTracker 【参考方案1】:

我遇到了同样的问题。我正在从 onItemClick 启动一个 Activity,这导致应用程序崩溃。

我认为问题在于尝试做一些应该只在主线程上完成的事情(比如启动一个活动)。

我已经实现了一个“处理程序”,它工作正常。

创建一个Handler作为全局变量:

private Handler handler;

在 onCreate 中设置处理程序,使其位于主线程上:

handler = new Handler();

在 onItemClick 中为处理程序创建一个帖子,我的看起来像这样:

handler.post(new Runnable() 

    @Override
    public void run() 
        // Do what ever...
    
);

【讨论】:

我不明白。如果问题是“应该只在主线程上完成的事情”,那么错误不应该出现在那个“事情”中吗?我看到堆栈跟踪的方式,错误出现在GestureDetector.java:587中,即(查看源代码):mVelocityTracker.recycle();这意味着mVelocityTracker在这种情况下是null。你如何由此推断这是一个线程问题? 感谢 Valer Dragos 的出色解决方案 +10【参考方案2】:

我还在onTouchEvent():587 中获得了 NPE。所以我开始使用支持库中的GestureDetectorCompat,它工作正常。

【讨论】:

以上是关于自 android 版本 3.0 起,图库 onItemClick 和 onTouchEvent 不能一起使用的主要内容,如果未能解决你的问题,请参考以下文章

带有 MultiTouch 的 Android 图库适配器?自定义图库还是自定义 ImageView?

Android 图库无法组合自定义标题

Android学习笔记之,调用系统图库,添加自定义字体,屏幕截图

Android自定义控件实例,圆形头像(图库 + 裁剪+设置),上传头像显示为圆形,附源码

图片来自 Android 6 中的图库(棉花糖)

如何在 Android 7.0 中从相机或图库中选择要裁剪的图像?