精华内容
下载资源
问答
  • 不说废话了,进入我们今天的主题吧。 先贴上前面内容的地址: Android手势ImageView三部曲(一) Android手势ImageView三部曲(二) Android手势ImageView三部曲(三) 前面我们讲到了ScaleGestureDetector这个...
  • GestureDetector

    2019-11-22 17:06:44
    一、GestureDetector GestureDetector 是检测手势的widget。在手机屏幕上的指定位置所产生的事件流都有GestureDetector决定是哪种手势。 GestureDetector({ Key key, this.child, this.onTapDown, this....

    一、GestureDetector

    GestureDetector 是检测手势的widget。在手机屏幕上的指定位置所产生的事件流都有GestureDetector决定是哪种手势。

    GestureDetector({
        Key key,
        this.child,
        this.onTapDown,
        this.onTapUp,
        this.onTap,
        this.onTapCancel,
        this.onSecondaryTapDown,
        this.onSecondaryTapUp,
        this.onSecondaryTapCancel,
        this.onDoubleTap,
        this.onLongPress,
        this.onLongPressStart,
        this.onLongPressMoveUpdate,
        this.onLongPressUp,
        this.onLongPressEnd,
        this.onVerticalDragDown,
        this.onVerticalDragStart,
        this.onVerticalDragUpdate,
        this.onVerticalDragEnd,
        this.onVerticalDragCancel,
        this.onHorizontalDragDown,
        this.onHorizontalDragStart,
        this.onHorizontalDragUpdate,
        this.onHorizontalDragEnd,
        this.onHorizontalDragCancel,
        this.onForcePressStart,
        this.onForcePressPeak,
        this.onForcePressUpdate,
        this.onForcePressEnd,
        this.onPanDown,
        this.onPanStart,
        this.onPanUpdate,
        this.onPanEnd,
        this.onPanCancel,
        this.onScaleStart,
        this.onScaleUpdate,
        this.onScaleEnd,
        this.behavior,
        this.excludeFromSemantics = false,
        this.dragStartBehavior = DragStartBehavior.start,
      }) 

    Flutter中的手势系统有两个独立的层。第一层有原始指针(pointer)事件,它描述了屏幕上指针(例如,触摸,鼠标和触控笔)的位置和移动。 第二层有手势,描述由一个或多个指针移动组成的语义动作。

    二、Pointers

    指针(Pointer)代表用户与设备屏幕交互的原始数据。有四种类型的指针事

    三、手势

    手势表示可以从多个单独的指针事件(甚至可能是多个单独的指针)识别的语义动作(例如,轻敲,拖动和缩放)。 完整的一个手势可以分派多个事件,对应于手势的生命周期(例如,拖动开始,拖动更新和拖动结束):

    1、Tap

    • onTapDown 指针已经在特定位置与屏幕接触
    • onTapUp 指针停止在特定位置与屏幕接触
    • onTap tap事件触发
    • onTapCancel 先前指针触发的onTapDown不会在触发tap事件

    2、双击

    • onDoubleTap 用户快速连续两次在同一位置轻敲屏幕.

    3、长按

    • onLongPress 指针在相同位置长时间保持与屏幕接触

    4、垂直拖动

    • onVerticalDragStart 指针已经与屏幕接触并可能开始垂直移动
    • onVerticalDragUpdate 指针与屏幕接触并已沿垂直方向移动.
    • onVerticalDragEnd 先前与屏幕接触并垂直移动的指针不再与屏幕接触,并且在停止接触屏幕时以特定速度移动

    5、水平拖动

    • onHorizontalDragStart 指针已经接触到屏幕并可能开始水平移动
    • onHorizontalDragUpdate 指针与屏幕接触并已沿水平方向移动
    • onHorizontalDragEnd 先前与屏幕接触并水平移动的指针不再与屏幕接触,并在停止接触屏幕时以特定速度移动
    展开全文
  • GestureDetector使用

    2018-11-10 08:57:36
    <户手势检测-GestureDetector使用详解>对应源码---完整版 博客<户手势检测-GestureDetector使用详解>对应源码,博客地址:http://blog.csdn.net/harvic880925/article/details/39520901
  • 主要为大家详细介绍了Android手势识别器GestureDetector的使用方法解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • NULL 博文链接:https://forlan.iteye.com/blog/2261417
  • 主要介绍了andorid 使用手势监听器GestureDetector遇到的不响应问题,具有很好的参考价值,对大家有所帮助。一起跟随小编过来看看吧
  • RecyclerViewExample Recyclerview + GestureDetector的东西
  • 主要介绍了android使用手势识别的方法,介绍了单击触摸屏触发的事件和双击事件的使用等方法,大家参考使用吧
  • 实例讲解Android手势识别类:GestureDetector类的使用

    前言

    • 手势识别在Android开发的应用非常常见
    • 今天carson将详细给大家讲解Android手势识别类:GestureDetector类的使用。(含实例讲解)

    Carson带你学Android系列文章
    Carson带你学Android:学习方法
    Carson带你学Android:四大组件
    Carson带你学Android:自定义View
    Carson带你学Android:异步-多线程
    Carson带你学Android:性能优化
    Carson带你学Android:动画


    目录


    简介

    下面,我将结合实例,详细介绍GestureDetector的使用接口 & 使用类。


    接口1:OnGestureListener

    1. 作用

    检测用户在屏幕的以下操作:按下瞬间、按压、长按、轻击、快速滑屏、拖动

    2. 使用步骤

    // 步骤1:创建手势检测器实例 & 传入OnGestureListener接口(需要复写对应方法)
    // 构造函数有3个,常用的是第二个
    // 1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
    // 2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
    // 3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
        GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
    
            // 1. 用户轻触触摸屏
            public boolean onDown(MotionEvent e) {
                Log.i("MyGesture", "onDown");
                return false;
            }
    
            // 2. 用户轻触触摸屏,尚未松开或拖动
            // 与onDown()的区别:无松开 / 拖动
            // 即:当用户点击的时,onDown()就会执行,在按下的瞬间没有松开 / 拖动时onShowPress就会执行
            public void onShowPress(MotionEvent e) {
                Log.i("MyGesture", "onShowPress");
            }
    
            // 3. 用户长按触摸屏
            public void onLongPress(MotionEvent e) {
                Log.i("MyGesture", "onLongPress");
            }
    
            // 4. 用户轻击屏幕后抬起
            public boolean onSingleTapUp(MotionEvent e) {
                Log.i("MyGesture", "onSingleTapUp");
                return true;
            }
    
            // 5. 用户按下触摸屏 & 拖动
            public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                    float distanceX, float distanceY) {
                Log.i("MyGesture", "onScroll:");
                return true;
            }
    
            // 6. 用户按下触摸屏、快速移动后松开
            // 参数:
            // e1:第1个ACTION_DOWN MotionEvent
            // e2:最后一个ACTION_MOVE MotionEvent
            // velocityX:X轴上的移动速度,像素/秒
            // velocityY:Y轴上的移动速度,像素/秒
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                   float velocityY) {
                Log.i("MyGesture", "onFling");
                return true;
            }
    
        });
    
    // 步骤2-1:让某个View检测手势 - 重写View的onTouch函数,将View的触屏事件交给GestureDetector处理,从而对用户手势作出响应
        View.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mGestureDetector.onTouchEvent(event);
                return true; // 注:返回true才能完整接收触摸事件
            }
        });
    
    // 步骤2-2:让某个Activity检测手势:重写Activity的dispatchTouchEvent函数,将触屏事件交给GestureDetector处理,从而对用户手势作出响应
      @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            mGestureDetector.onTouchEvent(ev); // 让GestureDetector响应触碰事件
            super.dispatchTouchEvent(ev); // 让Activity响应触碰事件
            return false;
        }
    

    3. 实例说明

    现在对一个TextView进行手势检测
    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        >
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="600dp"
            android:text="carson_ho Test"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    
    </LinearLayout>
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        TextView mTextView;
        GestureDetector mGestureDetector;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 步骤1:创建手势检测器实例 & 传入OnGestureListener接口(需要复写对应方法)
            mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
    
                // 1. 用户轻触触摸屏
                public boolean onDown(MotionEvent e) {
                    Log.i("MyGesture", "onDown");
                    return false;
                }
    
                // 2. 用户轻触触摸屏,尚未松开或拖动
                // 与onDown()的区别:无松开 / 拖动
                // 即:当用户点击的时,onDown()就会执行,在按下的瞬间没有松开 / 拖动时onShowPress就会执行
                public void onShowPress(MotionEvent e) {
                    Log.i("MyGesture", "onShowPress");
                }
    
                // 3. 用户长按触摸屏
                public void onLongPress(MotionEvent e) {
                    Log.i("MyGesture", "onLongPress");
                }
    
                // 4. 用户轻击屏幕后抬起
                public boolean onSingleTapUp(MotionEvent e) {
                    Log.i("MyGesture", "onSingleTapUp");
                    return true;
                }
    
                // 5. 用户按下触摸屏 & 拖动
                public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                        float distanceX, float distanceY) {
                    Log.i("MyGesture", "onScroll:");
                    return true;
                }
    
                // 6. 用户按下触摸屏、快速移动后松开
                // 参数:
                // e1:第1个ACTION_DOWN MotionEvent
                // e2:最后一个ACTION_MOVE MotionEvent
                // velocityX:X轴上的移动速度,像素/秒
                // velocityY:Y轴上的移动速度,像素/秒
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                       float velocityY) {
                    Log.i("MyGesture", "onFling");
                    return true;
                }
    
            });
    
            // 步骤2:让TextView检测手势:重写View的onTouch函数,将触屏事件交给GestureDetector处理,从而对用户手势作出响应
            mTextView = (TextView) findViewById(R.id.textView);
            mTextView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mGestureDetector.onTouchEvent(event);
                    return false;
                }
            });
        }
    }
    

    4. 示意图

    我在屏幕作出一系列手势进行测试


    接口2:OnDoubleTapListener

    1. 作用

    检测用户单击、双击屏幕

    2. 使用步骤

    // 步骤1:创建手势检测器实例
        // 注:使用OnDoubleTapListener接口时,需要使用GestureDetector,而GestureDetector的创建则必须传入OnGestureListener接口
        // 所以在使用OnDoubleTapListener接口时,也必须实现OnGestureListener接口
        // 构造函数有3个,常用的是第二个
        // 1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
        // 2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
        // 3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
            GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
    
                // 1. 用户轻触触摸屏
                public boolean onDown(MotionEvent e) {
                    Log.i("MyGesture", "onDown");
                    return false;
                }
    
                // 2. 用户轻触触摸屏,尚未松开或拖动
                // 与onDown()的区别:无松开 / 拖动
                // 即:当用户点击的时,onDown()就会执行,在按下的瞬间没有松开 / 拖动时onShowPress就会执行
                public void onShowPress(MotionEvent e) {
                    Log.i("MyGesture", "onShowPress");
                }
    
                // 3. 用户长按触摸屏
                public void onLongPress(MotionEvent e) {
                    Log.i("MyGesture", "onLongPress");
                }
    
                // 4. 用户轻击屏幕后抬起
                public boolean onSingleTapUp(MotionEvent e) {
                    Log.i("MyGesture", "onSingleTapUp");
                    return true;
                }
    
                // 5. 用户按下触摸屏 & 拖动
                public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                        float distanceX, float distanceY) {
                    Log.i("MyGesture", "onScroll:");
                    return true;
                }
    
                // 6. 用户按下触摸屏、快速移动后松开
                // 参数:
                // e1:第1个ACTION_DOWN MotionEvent
                // e2:最后一个ACTION_MOVE MotionEvent
                // velocityX:X轴上的移动速度,像素/秒
                // velocityY:Y轴上的移动速度,像素/秒
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                       float velocityY) {
                    Log.i("MyGesture", "onFling");
                    return true;
                }
    
            });
    
    // 步骤2:创建 & 设置OnDoubleTapListener接口实现类
        mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
    
            // 1. 单击事件
            // 关于OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的区别
            // onSingleTapConfirmed:再次点击(即双击),则不会执行
            // onSingleTapUp:手抬起就会执行
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Log.i("MyGesture", "onSingleTapConfirmed");
                return false;
            }
    
            // 2. 双击事件
            public boolean onDoubleTap(MotionEvent e) {
                Log.i("MyGesture", "onDoubleTap");
                return false;
            }
            // 3. 双击间隔中发生的动作
            // 指触发onDoubleTap后,在双击之间发生的其它动作,包含down、up和move事件;
            public boolean onDoubleTapEvent(MotionEvent e) {
                Log.i("MyGesture", "onDoubleTapEvent");
                return false;
            }
        });
    
    // 步骤3-1:让某个View检测手势 - 重写View的onTouch函数,将View的触屏事件交给GestureDetector处理,从而对用户手势作出响应
        View.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mGestureDetector.onTouchEvent(event);
                return true; // 注:返回true才能完整接收触摸事件
            }
        });
    
    // 步骤3-2:让某个Activity检测手势:重写Activity的dispatchTouchEvent函数,将触屏事件交给GestureDetector处理,从而对用户手势作出响应
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            mGestureDetector.onTouchEvent(ev); // 让GestureDetector响应触碰事件
            super.dispatchTouchEvent(ev); // 让Activity响应触碰事件
            return false;
        }
    

    3. 实例说明

    现在对一个TextView进行手势检测
    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        >
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="600dp"
            android:text="carson_ho Test"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    
    </LinearLayout>
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        TextView mTextView;
        GestureDetector mGestureDetector;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 步骤1:创建手势检测器实例 & 传入OnGestureListener接口(需要复写对应方法)
            mGestureDetector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
    
                // 1. 用户轻触触摸屏
                public boolean onDown(MotionEvent e) {
                    Log.i("MyGesture1", "onDown");
                    return false;
                }
    
                // 2. 用户轻触触摸屏,尚未松开或拖动
                // 与onDown()的区别:无松开 / 拖动
                // 即:当用户点击的时,onDown()就会执行,在按下的瞬间没有松开 / 拖动时onShowPress就会执行
                public void onShowPress(MotionEvent e) {
                    Log.i("MyGesture", "onShowPress");
                }
    
                // 3. 用户长按触摸屏
                public void onLongPress(MotionEvent e) {
                    Log.i("MyGesture", "onLongPress");
                }
    
                // 4. 用户轻击屏幕后抬起
                public boolean onSingleTapUp(MotionEvent e) {
                    Log.i("MyGesture", "onSingleTapUp");
                    return true;
                }
    
                // 5. 用户按下触摸屏 & 拖动
                public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                        float distanceX, float distanceY) {
                    Log.i("MyGesture", "onScroll:");
                    return true;
                }
    
                // 6. 用户按下触摸屏、快速移动后松开
                // 参数:
                // e1:第1个ACTION_DOWN MotionEvent
                // e2:最后一个ACTION_MOVE MotionEvent
                // velocityX:X轴上的移动速度,像素/秒
                // velocityY:Y轴上的移动速度,像素/秒
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                       float velocityY) {
                    Log.i("MyGesture", "onFling");
                    return true;
                }
    
            });
    
            // 步骤2:创建 & 设置OnDoubleTapListener接口实现类
            mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
    
                // 1. 单击事件
                // 关于OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的区别
                // onSingleTapConfirmed:再次点击(即双击),则不会执行
                // onSingleTapUp:手抬起就会执行
                public boolean onSingleTapConfirmed(MotionEvent e) {
                    Log.i("MyGesture", "onSingleTapConfirmed");
                    return false;
                }
    
                // 2. 双击事件
                public boolean onDoubleTap(MotionEvent e) {
                    Log.i("MyGesture", "onDoubleTap");
                    return false;
                }
                // 3. 双击间隔中发生的动作
                // 指触发onDoubleTap后,在双击之间发生的其它动作,包含down、up和move事件;
                public boolean onDoubleTapEvent(MotionEvent e) {
                    Log.i("MyGesture", "onDoubleTapEvent");
                    return false;
                }
            });
    
            // 步骤3:重写View的onTouch函数,将触屏事件交给GestureDetector处理,从而对用户手势作出响应
            mTextView = (TextView) findViewById(R.id.textView);
    
            mTextView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mGestureDetector.onTouchEvent(event);
                    return true;
                }
            });
        }
    }
    

    4. 测试效果

    日志效果如下


    使用类:SimpleOnGestureListener

    1. 作用

    集成了两个接口的手势检测功能

    2. 与上述两个接口的区别

    • OnGestureListener和OnDoubleTapListener接口里的函数都是强制必须重写的
    • 而SimpleOnGestureListener类的函数则可根据需要选择性复写,因为SimpleOnGestureListener类本身已经实现了这两个接口的所有函数,只是里面全是空的而已

    3. 使用步骤

    // 步骤1:创建手势检测器实例
        // 构造函数有3个,此处用的是第三个
        // 1. GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener);
        // 2. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener);
        // 3. GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);
        GestureDetector mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
    
            // OnGestureListener接口的函数
            // 1. 用户轻触触摸屏
            public boolean onDown(MotionEvent e) {
                Log.i("MyGesture1", "onDown");
                return false;
            }
    
            // 2. 用户轻触触摸屏,尚未松开或拖动
            // 与onDown()的区别:无松开 / 拖动
            // 即:当用户点击的时,onDown()就会执行,在按下的瞬间没有松开 / 拖动时onShowPress就会执行
            public void onShowPress(MotionEvent e) {
                Log.i("MyGesture", "onShowPress");
            }
    
            // 3. 用户长按触摸屏
            public void onLongPress(MotionEvent e) {
                Log.i("MyGesture", "onLongPress");
            }
    
            // 4. 用户轻击屏幕后抬起
            public boolean onSingleTapUp(MotionEvent e) {
                Log.i("MyGesture", "onSingleTapUp");
                return true;
            }
    
            // 5. 用户按下触摸屏 & 拖动
            public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                    float distanceX, float distanceY) {
                Log.i("MyGesture", "onScroll:");
                return true;
            }
    
            // 6. 用户按下触摸屏、快速移动后松开
            // 参数:
            // e1:第1个ACTION_DOWN MotionEvent
            // e2:最后一个ACTION_MOVE MotionEvent
            // velocityX:X轴上的移动速度,像素/秒
            // velocityY:Y轴上的移动速度,像素/秒
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                   float velocityY) {
                Log.i("MyGesture", "onFling");
                return true;
            }
    
            // OnDoubleTapListener的函数
            // 1. 单击事件
            // 关于OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的区别
            // onSingleTapConfirmed:再次点击(即双击),则不会执行
            // onSingleTapUp:手抬起就会执行
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Log.i("MyGesture", "onSingleTapConfirmed");
                return false;
            }
    
            // 2. 双击事件
            public boolean onDoubleTap(MotionEvent e) {
                Log.i("MyGesture", "onDoubleTap");
                return false;
            }
            // 3. 双击间隔中发生的动作
            // 指触发onDoubleTap后,在双击之间发生的其它动作,包含down、up和move事件;
            public boolean onDoubleTapEvent(MotionEvent e) {
                Log.i("MyGesture", "onDoubleTapEvent");
                return false;
            }
        });
    
    // 步骤2-1:让某个View检测手势 - 重写View的onTouch函数,将View的触屏事件交给GestureDetector处理,从而对用户手势作出响应
        View.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mGestureDetector.onTouchEvent(event);
                return true; // 注:返回true才能完整接收触摸事件
            }
        });
    
    // 步骤2-2:让某个Activity检测手势:重写Activity的dispatchTouchEvent函数,将触屏事件交给GestureDetector处理,从而对用户手势作出响应
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            mGestureDetector.onTouchEvent(ev); // 让GestureDetector响应触碰事件
            super.dispatchTouchEvent(ev); // 让Activity响应触碰事件
            return false;
        }
    

    4. 实例说明

    现在对一个TextView进行手势检测
    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        >
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="600dp"
            android:text="carson_ho Test"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    
    </LinearLayout>
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity {
    
        TextView mTextView;
        GestureDetector mGestureDetector;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 步骤1:创建手势检测器实例 & 传入OnGestureListener接口(需要复写对应方法)
            mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
    
                // OnGestureListener接口的函数
                // 1. 用户轻触触摸屏
                public boolean onDown(MotionEvent e) {
                    Log.i("MyGesture1", "onDown");
                    return false;
                }
    
                // 2. 用户轻触触摸屏,尚未松开或拖动
                // 与onDown()的区别:无松开 / 拖动
                // 即:当用户点击的时,onDown()就会执行,在按下的瞬间没有松开 / 拖动时onShowPress就会执行
                public void onShowPress(MotionEvent e) {
                    Log.i("MyGesture", "onShowPress");
                }
    
                // 3. 用户长按触摸屏
                public void onLongPress(MotionEvent e) {
                    Log.i("MyGesture", "onLongPress");
                }
    
                // 4. 用户轻击屏幕后抬起
                public boolean onSingleTapUp(MotionEvent e) {
                    Log.i("MyGesture", "onSingleTapUp");
                    return true;
                }
    
                // 5. 用户按下触摸屏 & 拖动
                public boolean onScroll(MotionEvent e1, MotionEvent e2,
                                        float distanceX, float distanceY) {
                    Log.i("MyGesture", "onScroll:");
                    return true;
                }
    
                // 6. 用户按下触摸屏、快速移动后松开
                // 参数:
                // e1:第1个ACTION_DOWN MotionEvent
                // e2:最后一个ACTION_MOVE MotionEvent
                // velocityX:X轴上的移动速度,像素/秒
                // velocityY:Y轴上的移动速度,像素/秒
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                                       float velocityY) {
                    Log.i("MyGesture", "onFling");
                    return true;
                }
    
                // OnDoubleTapListener的函数
                // 1. 单击事件
                // 关于OnDoubleTapListener.onSingleTapConfirmed()和 OnGestureListener.onSingleTapUp()的区别
                // onSingleTapConfirmed:再次点击(即双击),则不会执行
                // onSingleTapUp:手抬起就会执行
                public boolean onSingleTapConfirmed(MotionEvent e) {
                    Log.i("MyGesture", "onSingleTapConfirmed");
                    return false;
                }
    
                // 2. 双击事件
                public boolean onDoubleTap(MotionEvent e) {
                    Log.i("MyGesture", "onDoubleTap");
                    return false;
                }
                // 3. 双击间隔中发生的动作
                // 指触发onDoubleTap后,在双击之间发生的其它动作,包含down、up和move事件;
                public boolean onDoubleTapEvent(MotionEvent e) {
                    Log.i("MyGesture", "onDoubleTapEvent");
                    return false;
                }
            });
    
            // 步骤2:重写View的onTouch函数,将触屏事件交给GestureDetector处理,从而对用户手势作出响应
            mTextView = (TextView) findViewById(R.id.textView);
            mTextView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    mGestureDetector.onTouchEvent(event);
                    return true;
                }
            });
        }
    }
    

    5. 测试效果

    日志效果如下

    至此,关于Android手势识别类GestureDetector类使用讲解完毕。


    总结


    欢迎关注Carson_Ho的CSDN博客 与 公众号!

    博客链接:https://carsonho.blog.csdn.net/


    请帮顶 / 评论点赞!因为你的鼓励是我写作的最大动力!

    展开全文
  • GestureDetector:手势识别 这个类主要是用来处理手指在屏幕上的一些动作的,比如scroll,fling,down,press等。通过查看这个类的文档,发现,它内部定义了三个接口,分别是OnGestureListener,OnDoubleTapListener,...

    Gesture:手势
    Detector:侦查,识别
    GestureDetector:手势识别
    这个类主要是用来处理手指在屏幕上的一些动作的,比如scroll,fling,down,press等。通过查看这个类的文档,发现,它内部定义了三个接口,分别是OnGestureListener,OnDoubleTapListener,OnContextClickListener以及一个静态内部类,SimpleOnGestureListener,这个静态内部类实现了,前面提到的三个接口。
    这个静态内部类的好处是:
    1.当我们不想重写某个接口的那么多方法时,就可以使用这个静态内部类,由于这个静态内部类已经对三个接口做了空实现,所以我们不必再对这三个接口的方法都做实现,只需要重写我们关心的的方法即可。
    2.如果要监听多个手势动作,比如我们既要监听单击,又要监听双击屏幕的手势,则需要给
    gestureDetector对象设置多个监听对象。这时为了简化这些步骤,可以直接使用给gestureDetector对象设置一个SimpleOnGestureListener监听对象即可。
    为了能够更好的使用GestureDetector,我们就需要仔细了解这三个接口响应手势的回调方法,首先来看OnGestureListener接口中的各个方法。

        public interface OnGestureListener {
    
            //每次触摸屏幕,这个方法都会触发
            boolean onDown(MotionEvent e);
    
            //如果按下的时间超过180 ms,并且按下后,没有松开或者滑动,这个方法就会执行
    	//看文档上的注释是,用户已经执行了down 这个motionevent,并且用户还未执行移动或者抬起手指,
    	//这个事件通常是用于给用户一个视觉反馈,让用户知道他们的这个动作已经识别了。
            void onShowPress(MotionEvent e);
    
    	//一次单独的轻敲,这个方法就会执行
    	//触发顺序:
            //点击一下非常快的(不滑动)Touchup:
            //onDown->onSingleTapUp->onSingleTapConfirmed 
       	//点击一下稍微慢点的(不滑动)Touchup:
       	//onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
            boolean onSingleTapUp(MotionEvent e);
    
    	//手指在屏幕上移动,或者手指在屏幕上掠过(按下后,快速的滑动后松开),都会触发这个方法
    	//触发顺序:  
    	//手指在屏幕缓慢移动  onDown -> onShowPress(可能会有) -> 多个 onScroll
    	//手机在屏幕快速掠过  onDown -> 多个 onScroll -> onFling
    
    	// 参数解释:
    	// e1:第1个ACTION_DOWN MotionEvent
    	// e2:最后一个ACTION_MOVE MotionEvent
    	// velocityX:X轴上的移动速度,像素/秒
    	// velocityY:Y轴上的移动速度,像素/秒   
            boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
    
    	//手指在屏幕上长按,就会触发这个方法
    	// 触发顺序:onDown->onShowPress->onLongPress
            void onLongPress(MotionEvent e);
    
    	//用户手指在屏幕掠过(按下后,快速的滑动后松开)
            boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
        }
    
        public interface OnDoubleTapListener {
    	
    	//当手指在屏幕上单击时,这个方法会执行
    	//触发顺序:onDown -> onShowPress(可能有) -> onSingleTapUp -> onSingleTapConfirmed
    	//onSingleTapUp方法和onSingleConfirmed方法的区别是:不管是双击还是单击,手机离开屏幕的第一次,
    	//都会触发onSingleUp方法,如果手指单击屏幕,则会触发onSingleConfirmed方法,用于确定这次的手势就是单击
    	//如果手指双击屏幕,则不会触发onSinlgeConfirmed方法
            boolean onSingleTapConfirmed(MotionEvent e);
     
    	//当手指双击屏幕时,会执行这个方法
    	//触发顺序是:onDown -> onSingleTapUp ->onDoubleUp
            boolean onDoubleTap(MotionEvent e);
    
    	//当手指双击屏幕时,如果在onDoubleUp方法触发后发生了down,move,up等事件,则会执行这个方法
    	//触发顺序:onDown -> onSingleUp -> onDoubleUp ->onDoubleTapEvent ->onDown -> 多个onDoubleTapEvent
            boolean onDoubleTapEvent(MotionEvent e);
        }
    
        //这个接口是用于监听一些外部设备的手势
        public interface OnContextClickListener {
            boolean onContextClick(MotionEvent e);
        }
    

    了解完GestureDetector类的三个内部接口和一个静态内部类后,下面来看看,GestureDetector的构造方法

     public GestureDetector(Context context, OnGestureListener listener) {
            this(context, listener, null);
        }
    
        public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
            if (handler != null) {
                mHandler = new GestureHandler(handler);
            } else {
                mHandler = new GestureHandler();
            }
            mListener = listener;
            if (listener instanceof OnDoubleTapListener) {
                setOnDoubleTapListener((OnDoubleTapListener) listener);
            }
            if (listener instanceof OnContextClickListener) {
                setContextClickListener((OnContextClickListener) listener);
            }
            init(context);
        }
    
        //这个构造函数有些莫名其妙的,虽然要传入unused参数,但是传入的参数,并未使用,不知道是不是google的bug
        public GestureDetector(Context context, OnGestureListener listener, Handler handler,
                boolean unused) {
            this(context, listener, handler);
        }
    

    从上面这三个构造函数来看,最终都是调用了三个参数的构造函数。下面来看看三个参数的构造函数的具体实现:

        public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
            if (handler != null) {
                mHandler = new GestureHandler(handler);
            } else {
                mHandler = new GestureHandler();
            }
            mListener = listener;
            if (listener instanceof OnDoubleTapListener) {
                setOnDoubleTapListener((OnDoubleTapListener) listener);
            }
            if (listener instanceof OnContextClickListener) {
                setContextClickListener((OnContextClickListener) listener);
            }
            init(context);
        }
    

    从构造方法中,可以看出,构造方法内部,如果传递了handler,则将这个handler作为GestureHandler这个类的构造方法的参数创建一个handler对象,如果未传入handler对象,则使用GestureHandler创建一个hanler对象。将传入的OnGestureListener赋值给mLister,并调用init(context)方法进行一些相关的初始化操作。从GestureDetector的内部类GestureHandler的源码就可以看到,这两种创建handler的方式的唯一区别是,使用的Looper不同。下面看看GestureHandler这个类,它是GestureDetector的内部类,继承了Hander,其实就是一个Handler。

    private class GestureHandler extends Handler {
            GestureHandler() {
                super();
            }
    
            GestureHandler(Handler handler) {
                super(handler.getLooper());
            }
    
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case SHOW_PRESS:
                    mListener.onShowPress(mCurrentDownEvent);
                    break;
                    
                case LONG_PRESS:
                    dispatchLongPress();
                    break;
                    
                case TAP:
                    // If the user's finger is still down, do not count it as a tap
                    if (mDoubleTapListener != null) {
                        if (!mStillDown) {
                            mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
                        } else {
                            mDeferConfirmSingleTap = true;
                        }
                    }
                    break;
    
                default:
                    throw new RuntimeException("Unknown message " + msg); //never
                }
            }
        }
    

    如果我们是在主线程中直接使用两个参数的方式创建GestureDetector对象,则GestureDetector内部的handler使用的就是主线程的handler。如果在子线程中,创建GestureDetector对象,如果是使用两个参数的构造方法创建,则会报错
    Java.lang.RuntimeException: Can’t create handler inside thread that has not called Looper.prepare()
    所以,在子线程使用GestureDetector时,要特别注意。主要注意在子线程使用handler。如果要在子线程使用创建GestureDetector对象,则可以有如下三种方式:

    方式一:这种方式使用时,要注意onShowPress,onLongPress,onSingleTapConfirmed这三 个方法是在handleMessage方法中进行回调的,如果handler创建的线程是在子线程,则这三个方法在子线程回调的,所以,这三个方法中,不能处理ui的操作。具体代码如下:

     new Thread(new Runnable() {
                @Override
                public void run() {
                    Looper.prepare();
                    gestureDetector = new GestureDetector(GestureDetectorActivity2.this,gestureListener);
                    gestureDetector.setOnDoubleTapListener(onDoubleTapListener);
                    Looper.loop();
                }
            }).start();
    

    方式二:(用主线程的looper来创建handler,然后用GestureDetector的三个参数的构造函数来创建GestureDetector对象)

     new Thread(new Runnable() {
                @Override
                public void run() {
                    Handler handler = new Handler(Looper.getMainLooper());
                    gestureDetector = new GestureDetector(GestureDetectorActivity2.this,gestureListener,handler);
                    gestureDetector.setOnDoubleTapListener(onDoubleTapListener);
                }
            }).start();
    

    方式三:直接在主线程创建handler对象,在用这个handler去创建GestureDetector对象。

            final Handler handler = new Handler();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    gestureDetector = new GestureDetector(GestureDetectorActivity2.this,gestureListener,handler);
                    gestureDetector.setOnDoubleTapListener(onDoubleTapListener);
                }
            }).start();
    

    下面是直接在主线程中创建GestureDetector,有如下两种方式:
    方式一:

            GestureDetector gestureDetector = new GestureDetector(GestureDetectorActivity2.this,gestureListener);
            gestureDetector.setOnDoubleTapListener(onDoubleTapListener);
    

    方式二:(SimpleOnGestureListener里面的方法,按需实现,如果用不到,可以不去实现)

    GestureDetector  gestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener(){
                @Override
                public boolean onDown(MotionEvent e) {
                    return super.onDown(e);
                }
    
                @Override
                public void onShowPress(MotionEvent e) {
                    super.onShowPress(e);
                }
    
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return super.onSingleTapUp(e);
                }
    
                @Override
                public boolean onSingleTapConfirmed(MotionEvent e) {
                    return super.onSingleTapConfirmed(e);
                }
    
                @Override
                public boolean onDoubleTap(MotionEvent e) {
                    return super.onDoubleTap(e);
                }
    
                @Override
                public boolean onDoubleTapEvent(MotionEvent e) {
                    return super.onDoubleTapEvent(e);
                }
    
                @Override
                public void onLongPress(MotionEvent e) {
                    super.onLongPress(e);
                }
    
                @Override
                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                    return super.onScroll(e1, e2, distanceX, distanceY);
                }
    
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                    return super.onFling(e1, e2, velocityX, velocityY);
                }
            });
    

    GestureDetector的原理就是:通过拦截onTouchEvent中的各个MotionEvent,在将自己定义的一套规则,比如什么是单击,什么是双击,来将各个MotionEvent做更加细致的划分,通过自己内部的handler,发送这些自己定义的规则的(比如单击事件)消息,然后在handlerMessage
    方法中,调用GestureListener接口中相应的回调方法,来实现onShowPress,onLongPress,onSingleTapConfirmed操作的监听。在GestureDetector的onTouchEvent方法中,进行onDown,onSingleTapUp,onDoubleTap,onDoubleTapEvent,onScroll,onFling这些方法的回调。

    使用步骤是:
    1.创建GestureDetector.SimpleOnGestureListener simpleLinener = new GestureDetector.SimpleOnGestureListener(){//实现自己关心的对调方法}对象
    2.创建GestureDetector对象
    GestureDetector gestureDetector = new GestureDetector(simpleLinener);
    3.在要监听的view的onTouchListener中处理MotionEvent的动作
    tv.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    gestureDetector.onTouchEvent(event);
    return false;
    }
    });

    参考:
    安卓自定义View进阶-手势检测(GestureDetector)
    https://www.gcssloop.com/customview/gestruedector

    用户手势检测-GestureDetector使用详解
    https://blog.csdn.net/harvic880925/article/details/39520901

    展开全文
  • Android GestureDetector详解

    千次阅读 2019-03-01 13:24:46
    } public GestureDetector(Context context, OnGestureListener listener, Handler handler) { } public GestureDetector(Context context, OnGestureListener listener, Handler handler, boolean unused) { this...

    1. 事件监听的方法

    在android应用层上主要有两个层面的触摸事件监听,一个是Activity层,另一个是View层。方法主要有三种:
    第一是Activity中重写父类中的public boolean onTouchEvent(MotionEvent event)方法;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
    

    第二个是重写View类中的GestDetector.OnGestureListener接口中定义的boolean onTouch(View v, MotionEvent event);

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return false;
    }
    

    第三个是利用GestureDetector.onTouchEvent(event)View.onTouch方法中来接管事件处理

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }
    

    view上的事件被分发到view上时触发onTouch方法的回调, 如果这个方法返回false时,表示事件处理失败,该事件就会被传递给相应的Activity中的onTouchEvent方法来处理。
    如果该方法返回true时,表示该事件已经被onTouch函数处理完,不会上传到activity中处理。

    2. GestureDector类

    GestureDector类需要注意以下内容:

    • OnGestureListener接口
    • OnDoubleTapListener双击接口
    • SimpleOnGestureListener 类(实现了类内的三个接口)
    • onTouchEvent()方法
    • setOnDoubleTapListener()双击监听

    当屏幕上发生特定的触摸事件,就会去回调GestureDector.OnGestureListenerGestureDetector.OnDoubleTapListener接口中相应的回调函数来监测各样的手势和事件,并且通知用户。但是这些触发函数都没有具体的实现,我们必须实现这些接口,并重写这些方法的具体实现。

    GestureDetector类中已经为我们定义了一个静态内部类SimpleOnGestureListener,它实现了OnGestureListenerOnDoubleTapListenerOnContextClickListener接口,定义为

    public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
            OnContextClickListener 
    

    SimpleOnGestureListener类内重写接口中的所有方法,但是都是空实现,返回的布尔值都是false。主要作用是方便我们继承这个类有选择的复写回调方法,而不是实现接口去重写所有的方法。

    onTouchEvent()方法用来分析传入的事件,如果匹配的话就去触发OnGestureListener中相应的回调方法。
    如果要监听双击事件必须调用GestureDector.setOnDoubleTapListener()

    3. GestureDetector使用方法

    第一步: 实现OnGestureListener接口中的方法(可以使用匿名内部类或实现了接口的类实例)
    内部类形式

    class MyGestureListener implements GestureDetector.OnGestureListener {
    
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }
    
        @Override
        public void onShowPress(MotionEvent e) {
    
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }
    
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }
    
        @Override
        public void onLongPress(MotionEvent e) {
    
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    }
    

    匿名内部类形式

    mGestureDetector = new GestureDetector(mContext, new GestureDetector.OnGestureListener() {
            @Override
            public boolean onDown(MotionEvent e) {
                return false;
            }
    
            @Override
            public void onShowPress(MotionEvent e) {
    
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return false;
            }
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                return false;
            }
    
            @Override
            public void onLongPress(MotionEvent e) {
    
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                return false;
            }
        });
    

    第二步: 创建GestureDetector类的实例,构造函数如下:

    public GestureDetector(OnGestureListener listener, Handler handler) {
        this(null, listener, handler);
    }
    
    public GestureDetector(OnGestureListener listener) {
        this(null, listener, null);
    }
    
    public GestureDetector(Context context, OnGestureListener listener) {
        this(context, listener, null);
    }
    
    public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
    }
    
    public GestureDetector(Context context, OnGestureListener listener, Handler handler,
            boolean unused) {
        this(context, listener, handler);
    }
    

    前两个已经废弃了。

    mGestureDetector = new GestureDetector(mContext,new MyGestureListener());
    

    第三步: 实现View.OnTouchListener接口,重写onTouch()方法
    第四步:onTouch()方法中拦截事件处理,将控制权交给GestureDector

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }
    

    第五步: 调用控件的View.setOnTouchListener()将接口的具体实现的引用传递进去或者如果是监听双击的话调用GestureDetector .setOnDoubleTapListener()

    super.setOnTouchListener(this);
    mGestureDetector.setOnDoubleTapListener(new MyGestureListener());
    

    完整代码

    package com.example.gesturetest;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.View;
    
    /*
     * Created by pingkun.huang on 2016/4/16.
     */
    public class MyView extends View implements View.OnTouchListener{
        private Context mContext;
        private GestureDetector mGestureDetector;
        private static final String TAG = "MyView";
        public MyView(Context context) {
            super(context);
            initData(context);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initData(context);
        }
    
        public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initData(context);
        }
    
        private void initData(Context context) {
            this.mContext = context;
            super.setOnTouchListener(this);
            super.setClickable(true);
            super.setLongClickable(true);
            super.setFocusable(true);
            mGestureDetector = new GestureDetector(mContext,new MyGestureListener());
            mGestureDetector.setOnDoubleTapListener(new MyGestureListener());
        }
    
        /*
         * 当该view上的事件被分发到view上时触发该方法的回调
         * 如果这个方法返回false时,该事件就会被传递给Activity中的onTouchEvent方法来处理
         * 如果该方法返回true时,表示该事件已经被onTouch函数处理玩,不会上传到activity中处理
         * 该方法属于View.OnTouchListening接口
         */
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return mGestureDetector.onTouchEvent(event);
        }
    
        /*
         * 手势监听类
         */
        class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
    
            public MyGestureListener() {
                super();
            }
    
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                Log.e(TAG, "onDoubleTap");
                return true;
            }
    
            @Override
            public boolean onDoubleTapEvent(MotionEvent e) {
                Log.e(TAG, "onDoubleTapEvent");
                return true;
            }
    
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                Log.e(TAG, "onSingleTapConfirmed");
                return true;
            }
    
            @Override
            public boolean onContextClick(MotionEvent e) {
                Log.e(TAG, "onContextClick");
                return true;
            }
    
            @Override
            public boolean onDown(MotionEvent e) {
                Log.e(TAG, "onDown");
                return true;
            }
    
            @Override
            public void onShowPress(MotionEvent e) {
                Log.e(TAG, "onShowPress");
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                Log.e(TAG, "onSingleTapUp");
                return true;
            }
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                Log.e(TAG, "onScroll");
                return true;
            }
    
            @Override
            public void onLongPress(MotionEvent e) {
                Log.e(TAG, "onLongPress");
            }
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                Log.e(TAG, "onFling");
                return true;
            }
        }
    }
    

    MyView是一个自定义控件继承了View实现了View.OnTouchListener。监听的方法用的是继承SimpleOnGestureListener类,重写了所有方法,仅打印log日志,具体功能自己根据业务重写。

    4. GesturetDetector.OnGestureListener 接口

    class MyGestureListener implements GestureDetector.OnGestureListener {
    
        /*
         * 每按一下屏幕立即触发
         */
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }
        
        /*
         * 用户按下屏幕并且没有移动或松开。主要是提供给用户一个可视化的反馈,告诉用户他们的按下操作已经
         * 被捕捉到了。如果按下的速度很快只会调用onDown(),按下的速度稍慢一点会先调用onDown()再调用onShowPress().
         */
        @Override
        public void onShowPress(MotionEvent e) {
    
        }
    
        /*
         * 一次单纯的轻击抬手动作时触发
         */
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            return false;
        }
    
        /*
         * 屏幕拖动事件,如果按下的时间过长,调用了onLongPress,再拖动屏幕不会触发onScroll。拖动屏幕会多次触发
         * @param e1 开始拖动的第一次按下down操作,也就是第一个ACTION_DOWN
         * @parem e2 触发当前onScroll方法的ACTION_MOVE
         * @param distanceX 当前的x坐标与最后一次触发scroll方法的x坐标的差值。
         * @param diastancY 当前的y坐标与最后一次触发scroll方法的y坐标的差值。
         */
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }
    
        /*
         * 长按。在down操作之后,过一个特定的时间触发
         */
        @Override
        public void onLongPress(MotionEvent e) {
    
        }
    
        /*
         * 按下屏幕,在屏幕上快速滑动后松开,由一个down,多个move,一个up触发
         * @param e1 开始快速滑动的第一次按下down操作,也就是第一个ACTION_DOWN
         * @parem e2 触发当前onFling方法的move操作,也就是最后一个ACTION_MOVE
         * @param velocityX:X轴上的移动速度,像素/秒
         * @parram velocityY:Y轴上的移动速度,像素/秒
         */
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }
    }
    

    快按屏幕:onDown
    慢按屏幕:onDown–>onShowPress
    按下屏幕等待一段时间onDown–>onShowPress–>onLongPress
    拖动屏幕:onDown–>onShowPress–>onScroll(多个)–>onFling
    快速滑动:onDown–>onScroll(多个)–>onFling

    5. GesttureDetector.OnDoubleTapListener 接口

    class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener {
    
        /*
         * 单击事件。用来判定该次点击是单纯的SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,
         * 如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,
         * 然后触发SingleTapConfirmed事件。触发顺序是:OnDown->OnsingleTapUp->OnsingleTapConfirmed
         * 关于onSingleTapConfirmed和onSingleTapUp的一点区别:二者的区别是:onSingleTapUp,只要手抬起就会执行,
         * 而对于onSingleTapConfirmed来说,如果双击的话,则onSingleTapConfirmed不会执行。
         */
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            return false;
        }
    
        /*         
         * 双击事件
         */
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return false;
        }
    
        /*
         * 双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件
         */
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            return false;
        }
    }
    

    双击:onDown–>onSingleTapUp–>onDoubleTap–>onDoubleTapEvent–>onDown–>onDoubleTapEvent

    6. GesttureDetector.SimpleOnGestureListener 类

    结合了OnGestureListenerOnDoubleTapListenerOnContextClickListener中的所有方法,可以有选择的去重写其中的方法,参考前两节。

    展开全文
  • GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener); GestureDetector gestureDetector=new GestureDetector(Context context, GestureDetector....
  • GestureDetector是Flutter的手势检测器,它会尝试识别与其非null的回调相对应的手势。如果此Widget组件具有子控件,那么它的大小调整行为将遵从该子控件件。如果它没有子控件,那么它将变大以适合父控件。 默认情况...
  • GestureDetector 的作用: 检测各种手势和事件,使用的使用一般和onTouchEvent 方法结合在一起使用 下面主要说的内容是GestureDetector 和ScaleGestureDetector 1GestureDetector 里面有一些回调接口下面说下 ...
  • 三、GestureDetector.OnDoubleTapListener---接口 1、构建 有两种方式设置双击监听: 方法一:新建一个类同时派生自OnGestureListener和OnDoubleTapListener: [java] view plain copy private class ...
  • Android 手势检测,主要是 GestureDetector 相关内容的用法和注意事项,本文依旧属于事件处理这一体系,部分内容会涉及到之前文章提及过的知识点,如果你没看过之前的文章,可以到自定义 View 系列来查看这些内容。...
  • Android手势识别GestureDetector详解

    万次阅读 2017-04-07 11:54:13
     * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,将捕捉到的MotionEvent交给GestureDetector     * 来分析是否有合适的callback函数来处理用户的手势     */     public   boolean...
  • mGestureDetector = new GestureDetector(context, new GestureDetector.OnGestureListener() { @Override public boolean onDown(MotionEvent e) { return false; } @Override public void onShowPress...
  • 这时也就引出了手势监测的概念,所谓的手势监测,说白了就是对于 GestureDetector 的用法的使用和注意要点的学习。注:由于缩放手势独有的复杂性,我打算后期将其单独拿出来归纳总结。 像网上其他将手势监听的博客...
  • 引言 上一篇文章 深入理解Flutter的Listener组件 介绍了触控事件的监听...GestureDetector的内部实现使用的是Listener组件,如果对Listener还不太熟悉,可以先了解一下Listener的原理。 源码解析 一、GestureDetec...
  • flutter GestureDetector添加点击效果

    千次阅读 2021-10-27 12:20:46
    做法为把GestureDetector替换为InkWell,一个带onTap和child属性的组件,然后就有点击效果了。如果child是有背景色/图片的Container,可以将其替换为Ink,一个和Container用法类似的组件。 原文链接
  • 利用GestureDetector实现页面滑动Demo
  • 如点击一个文字加图标,外面是Row,发现点击区域很小,代码如下: GestureDetector( onTap: () async { Routers.push(Routers.regularListPage, context, callBack: (value) => homeModel.refreshData());
  • GestureDetector使用详解

    2020-06-20 09:53:26
    Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势,主要是通过他的onTouchEvent(event)方法完成了不同手势的识别。虽然他能识别手势,但是不同的手势要...
  • 学习flutter 肯定是快乐的,实际做项目必然是充满挑战。为了迎接未来的挑战,我们需要对flutter有更深入的了解 GestureDetector 类深入研究 ...如果GestureDetector 的child属性不空,GestureDetector将自己大...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,276
精华内容 4,910
关键字:

gesturedetector