Android中Gesture手势的基本用法(总结)

应用场景:

(1)左右上下滑动屏幕的事件监听。比如,上拉弹出自定义的底部布局之类的,换页之类的等等。

(2)画一些不规则的几何图形。

执行顺序:

  • 1.手指触碰屏幕时,触发MotionEvent事件!
  • 2.该事件被OnTouchListener监听,可在它的onTouch()方法中获得该MotionEvent对象!
  • 3.通过GestureDetector转发MotionEvent对象给OnGestureListener
  • 4.我们可以通过OnGestureListener获得该对象,然后获取相关信息,以及做相关处理!

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

功能代码:

package com.deepreality.summarizetestdemo;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Toast;

public class GestureActivity extends AppCompatActivity {

    private Context mContext;
    private static String TAG = "GestureListener---";

    private MyGestureListener myGestureListener;
    private GestureDetector gestureDetector;

    private static int MIN_MOVE = 200;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gesture);

        baseDataInit();
        bindViews();
        viewsAddListener();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private void baseDataInit() {
        mContext = this;
        myGestureListener = new MyGestureListener();
        gestureDetector = new GestureDetector(mContext, myGestureListener);
    }

    private void bindViews() {

    }

    private void viewsAddListener() {

    }

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

    class MyGestureListener implements GestureDetector.OnGestureListener {

        @Override
        public boolean onDown(MotionEvent e) {
            Log.e(TAG, "onDown:按下");
            return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {
            Log.e(TAG, "onShowPress:手指按下一段时间,但是还没到长按");
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            Log.e(TAG, "onSingleTapUp:手指离开屏幕的一瞬间");
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.e(TAG, "onScroll:在屏幕上滑动");
            return false;
        }

        @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:迅速滑动并松开");
            if (e1.getY() - e2.getY() > MIN_MOVE) {
                Toast.makeText(mContext, "上拉操作", Toast.LENGTH_SHORT).show();
            } else if (e1.getY() - e2.getY() < MIN_MOVE) {
                Toast.makeText(mContext, "下拉操作", Toast.LENGTH_SHORT).show();
            }
            Log.e("e1-Y", e1.getY() + "");
            Log.e("e2-Y", e2.getY() + "");
            return true;
        }
    }
}

特别注意:

这里用到的是OnGestureListener,需要实现该接口的所有方法,我这边如果仅仅使用滑动操作,显然不太合理。那么怎么处理呢?使用SimpleOnGestureListener即可,需要哪个,就实现哪个方法。

 

附加:

如何在屏幕画一些不规则图形?比如,银行常用的电子签名功能。

这里用到的是:GestureOverlayView(手势编辑组件)

如何使用呢?

(1)布局文件:

<android.gesture.GestureOverlayView
    android:id="@+id/GestureComponent_GOVGesture"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gestureColor="@color/colorBlack"
    android:gestureStrokeType="multiple"></android.gesture.GestureOverlayView>

(2)获取组件并进行相关设置:

//设置手势编辑组件
//手势的颜色
GOVGesture.setGestureColor(getResources().getColor(R.color.colorBlack));
//手势的粗细
GOVGesture.setGestureStrokeWidth(5);
/*手势绘制完成后淡出屏幕的时间间隔,即绘制完手指离开屏幕后相隔多长时间手势从屏幕上消失;
 * 可以理解为手势绘制完成手指离开屏幕后到调用onGesturePerformed的时间间隔
 * 默认值为420毫秒,这里设置为2秒
 */
GOVGesture.setFadeOffset(2000);

(3)添加手势编辑完成监听事件

GOVGesture.addOnGesturePerformedListener(this);

(4)通过手势对象获取ImageView所需的Bitmap对象。

//给ImageView赋值手势
bitmap = gesture.toBitmap(100, 100, 10, getResources().getColor(R.color.colorBlack));
ivGesture.setImageBitmap(bitmap);

如何保存和比对手势呢?

(1)保存手势

//文件对应的手势库(保存)
GestureLibrary gestureLib = GestureLibraries.fromFile("/mnt/sdcard/mygestures");
gestureLib.addGesture(etName.getText().toString(), gesture);
gestureLib.save();

(2)比对手势

第一步:

//加载本地手势库
GestureLibrary gestureLibrary = GestureLibraries.fromFile("mmt/sdcard/mygestures");
if (gestureLibrary.load()) {
    Toast.makeText(mContext, "手势库加载成功", Toast.LENGTH_SHORT).show();
} else {
    Toast.makeText(mContext, "手势库加载失败", Toast.LENGTH_SHORT).show();
}

第二步:

在GesturePerformedListener接口方法OnGesturePerformed里进行识别操作:

//识别用户刚绘制的手势
ArrayList<Prediction> predictions = gestureLibrary.recognize(gesture);
ArrayList<String> result = new ArrayList<String>();
//遍历所有找到的Prediction对象
for (Prediction prediction : predictions) {
    if (prediction.score > 2.0) {
        result.add("与手势【" + prediction.name + "】相似度为" + prediction.score);
    }
}
if (result.size() > 0) {
    ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(mContext,
            android.R.layout.simple_dropdown_item_1line, result.toArray());
    new AlertDialog.Builder(mContext).setAdapter(adapter, null).setPositiveButton("确定", null).show();
}else{
    Toast.makeText(mContext,"无法找到匹配的手势!", Toast.LENGTH_SHORT).show();
}

对了,不要忘记添加用户权限哦!

 

附加:如何在Fragment中添加监听OnTouchEvent。

1、在Fragment的父Activity中添加接口

/** 保存MyTouchListener接口的列表 */
private ArrayList<MyTouchListener> myTouchListeners = new ArrayList<>();

/** 提供给Fragment通过getActivity()方法来注册自己的触摸事件的方法 */
public void registerMyTouchListener(MyTouchListener listener) {
    myTouchListeners.add(listener);
}

/** 提供给Fragment通过getActivity()方法来取消注册自己的触摸事件的方法 */
public void unRegisterMyTouchListener(MyTouchListener listener) {
    myTouchListeners.remove(listener);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    for (MyTouchListener listener : myTouchListeners) {
        listener.onTouchEvent(ev);
    }
    return super.dispatchTouchEvent(ev);
}
public interface MyTouchListener {
    /** onTouchEvent的实现 */
    boolean onTouchEvent(MotionEvent event);
}

2、在相应的Fragment中注册,取消注册监听接口

/** 触摸事件的注册 */
((MainActivity)this.getActivity()).registerMyTouchListener(myTouchListener);
/** 触摸事件的取消注册 */
((MainActivity)this.getActivity()).unRegisterMyTouchListener(myTouchListener);
/** 接收MainActivity的Touch回调的对象,重写其中的onTouchEvent函数 */
MainActivity.MyTouchListener myTouchListener = new MainActivity.MyTouchListener() {
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //处理手势事件(根据个人需要去返回和逻辑的处理)
        return gestureDetector.onTouchEvent(event);
    }
};

class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (e1.getY() - e2.getY() > 20) {
            FABtnWrite.setVisibility(View.GONE);
        } else if (e1.getY() - e2.getY() < 20) {
            FABtnWrite.setVisibility(View.VISIBLE);
        }
        return true;
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值