Android Gesture 手势

相信大家对手势应该不会陌生吧?如果还不知道是啥概念的,请解锁手机,然后从屏幕上方往下滑,就会滑出 通知快捷设置 界面

手势 (Gesture)是一种连续触碰的行为,比如左右上下滑动屏幕,又或者画一些不规则的几何图形

手势可以大大提升用户体验,比如 Scroll 手势在浏览器中个滚屏,Fling 在浏览器中的换页等

Android Gesture

Android 提供了对手势的支持

  1. 提供手势检测,并为手势识别提供了相应的监听器
  2. 可以让开发者自行添加手势,并且提供了相应的 API 识别用户手势

Android 中手势交互的执行顺序

  1. 手指触碰屏幕时,触发 MotionEvent 事件
  2. 该事件被 OnTouchListener 监听,可在它的 onTouch() 方法中获得该 MotionEvent 对象
  3. 通过 GestureDetector 转发 MotionEvent 对象给 OnGestureListener

可以通过 OnGestureListener 获得该对象,然后获取相关信息,以及做相关处理

说明
MotionEvent 这个类用于封装手势、触摸笔、轨迹球等等的动作事件。其内部封装了两个重要的属性X和Y,这两个属性分别用于记录横轴和纵轴的坐标
GestureDetector 识别各种手势
OnGestureListener 这是一个手势交互的监听接口,其中提供了多个抽象方法,并根据 GestureDetector 的手势识别结果调用相对应的方法。

GestureListener

监听手势的关键是 GestureListener ,它提供了下述的回调方法

手势 回调方法 说明
按下 onDown() 刚刚手指接触到触摸屏的那一刹那,就是触的那一下
抛掷 onFling() 手指在触摸屏上迅速移动,并松开的动作
长按 onLongPress() 手指按在持续一段时间,并且没有松开
滚动 onScroll() 手指在触摸屏上滑动
按住 onShowPress() 手指按在触摸屏上,它的时间范围在按下起效
在长按之前
抬起 onSingleTapUp() 手指离开触摸屏的那一刹那

知道了 GestureListener 的相关方法后,实现手势检测也很简单

  1. 创建 GestureDetector 对象,创建时需实现 GestureListener 传入
  2. Activity 或者特定组件上的 TouchEvent 的事件交给 GestureDetector 处理

范例

我们写一简单的 demo 来看看这些回调方法

  1. 创建一个 空的 Android 项目 cn.twle.android.Gesture

  2. 修改 activity_main.xml 删除 TextView

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </LinearLayout>
    
  3. 修改 MainActivity.java 添加手势支持

    package cn.twle.android.gesture;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    
    public class MainActivity extends AppCompatActivity {
    
        private MsGestureListener mListener;
        private GestureDetector mDetector;
        private final static String TAG = "MsGesture";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //实例化 GestureListener  GestureDetector 对象
            mListener = new MsGestureListener();
            mDetector = new GestureDetector(this, mListener);
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return mDetector.onTouchEvent(event);
        }
    
        //自定义一个GestureListener,这个是View类下的,别写错哦!!!
        private class MsGestureListener implements GestureDetector.OnGestureListener {
    
            @Override
            public boolean onDown(MotionEvent motionEvent) {
                Log.d(TAG, "onDown:按下");
                return false;
            }
    
            @Override
            public void onShowPress(MotionEvent motionEvent) {
                Log.d(TAG, "onShowPress:手指按下一段时间,不过还没到长按");
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent motionEvent) {
                Log.d(TAG, "onSingleTapUp:手指离开屏幕的一瞬间");
                return false;
            }
    
            @Override
            public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
                Log.d(TAG, "onScroll:在触摸屏上滑动");
                return false;
            }
    
            @Override
            public void onLongPress(MotionEvent motionEvent) {
                Log.d(TAG, "onLongPress:长按并且没有松开");
            }
    
            @Override
            public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
                Log.d(TAG, "onFling:迅速滑动,并松开");
                return false;
            }
        }
    
    }
    

对应操作截图

  1. 按下后立即松开

  2. 长按后松开

  3. 轻轻一滑,同时松开

  4. 按住后不放持续做滑动操作

SimpleOnGestureListener

从代码上来,如果我们要实现 OnGestureListener 需要重写太多的手势,而我们仅仅想用的仅仅是滑动而已

有没有更好的解决办法呢?

有的,Android 官方提供了一个 SimpleOnGestureListener

使用方法只需要把上述的 OnGestureListener 替换成 SimpleOnGestureListener

范例 2

这次我们使用 SimpleOnGestureListener 写一个 下滑关闭 Activity,上滑启动新的 Activity


  1. 创建一个 空的 Android 项目 cn.twle.android.SimpleGesture

  2. 修改 MainActivity.java 添加 SimpleOnGestureListener

    package cn.twle.android.simplegesture;
    
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        private GestureDetector mDetector;
        private final static int MIN_MOVE = 200;   //最小距离
        private MyGestureListener mgListener;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //实例化SimpleOnGestureListener与GestureDetector对象
            mgListener = new MyGestureListener();
            mDetector = new GestureDetector(this, mgListener);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            return mDetector.onTouchEvent(event);
        }
    
        //自定义一个GestureListener,这个是View类下的,别写错哦!!!
        private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
    
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float v, float v1) {
                if(e1.getY() - e2.getY() > MIN_MOVE){
                    startActivity(new Intent(MainActivity.this, MainActivity.class));
                    Toast.makeText(MainActivity.this, "通过手势启动Activity", Toast.LENGTH_SHORT).show();
                }else if(e1.getY() - e2.getY()  < MIN_MOVE){
                    finish();
                    Toast.makeText(MainActivity.this,"通过手势关闭Activity",Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        }
    
    }
    

参考文档

  1. Android GestureDetector

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.