Android 手势监听学习总结

android的简单手势监听一般用onTouchListner接口,复杂手势监听一般用Detector来接替onTouch的处理。

手势监听后的处理涉及android坐标系统的问题。

多点触点则一般用event.getPointerCount()获取目前的触摸点的个数,用event.getX(index)、event.getY(index)获得第index个触摸点的坐标。


一. 用View.OnTouchListener接口监听简单手势

在Android中,简单的手势监听用实现View类的View.OnTouchListener接口的方法即可


如,对某个view进行手势监听

RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rlayout);

		relativeLayout.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					// 按下屏幕的操作
					break;
				case MotionEvent.ACTION_MOVE:
					// 在屏幕上移动的操作
					break;
				case MotionEvent.ACTION_UP:
					// 离开屏幕的操作
					break;
				case (MotionEvent.ACTION_CANCEL):
					// 手势撤消的操作
					// 一般认为不能由用户主动触发。
					// 系统在运行到一定程度下无法继续响应你的后续动作时会产生此事件
					break;
				default:
					break;
				}
				// 这个返回值如果是false的话,那么它只会接受到第一个ACTION_DOWN的效果,
				// 后面的它认为没有触发,所以要想继续监听后续事件,需要返回值为true
				return true;
			}
		});

需要注意的是,onTouch()方法要返回true,否则只会监听ACTION_DOWN


也可以对整个Activity进行监听,如:

public class MyActivity extends Activity {

	private static final String DEBUG_TAG = "MyActivity";

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

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int action = MotionEventCompat.getActionMasked(event);

		switch (action) {
		case (MotionEvent.ACTION_DOWN):
			Log.d(DEBUG_TAG, "Action was DOWN");
			break;
		case (MotionEvent.ACTION_MOVE):
			Log.d(DEBUG_TAG, "Action was MOVE");
			break;
		case (MotionEvent.ACTION_UP):
			Log.d(DEBUG_TAG, "Action was UP");
			break;
		case (MotionEvent.ACTION_CANCEL):
			Log.d(DEBUG_TAG, "Action was CANCEL");
			break;
		default:
			break;
		}
		return true;
	}

}

二. 用GestureDetector监听复杂手势

对于复杂手势的监听,一般用GestureDetector,而且为了提高版本的兼容,一般用support.v4中的GestureDetectorCompat

如:对某个view进行手势监听

package com.example.touch;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.GestureDetectorCompat;
import android.util.Log;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.LinearLayout;

public class MyActivity2 extends Activity {

	private static final String TAG = "MyActivity2";

	// 用GestureDetectorCompat替换GestureDetector,GestureDetectorCompat兼容的版本较广
	private GestureDetectorCompat mDetector;

	private LinearLayout linearLayout;

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

		initView();

		initDetector();

		setTouchListener();
	}

	// 对linearLayout设置手势监听
	private void setTouchListener() {
		linearLayout.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				mDetector.onTouchEvent(event);
				return true;
			}
		});
	}

	// // 让GestureDetectorCompat来接替处理
	// @Override
	// public boolean onTouchEvent(MotionEvent event){
	// this.mDetector.onTouchEvent(event);
	// // Be sure to call the superclass implementation
	// return super.onTouchEvent(event);
	// }

	private void initView() {
		linearLayout = (LinearLayout) findViewById(R.id.linearlayout);
	}

	// 初始化手势监听器Detector
	private void initDetector() {
		mDetector = new GestureDetectorCompat(MyActivity2.this,
				new MytGestureListener());
	}

	/**
	 * 手势监听器
	 */
	private class MytGestureListener extends SimpleOnGestureListener {

		// Touch down时触发
		@Override
		public boolean onDown(MotionEvent e) {
			Log.d(TAG, "onDown");
			return super.onDown(e);
		}

		// 在Touch down之后一定时间(115ms)触发
		@Override
		public void onShowPress(MotionEvent e) {
			Log.d(TAG, "onShowPress");
		}

		// 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发
		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			Log.d(TAG, "onSingleTapUp");
			return super.onSingleTapUp(e);
		}

		// 滑动时触发
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			Log.d(TAG, "onScroll");
			return super.onScroll(e1, e2, distanceX, distanceY);
		}

		// 抛掷
		// 滑动一段距离,up时触发
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			Log.d(TAG, "onFling");
			return super.onFling(e1, e2, velocityX, velocityY);
		}

		// 长按后触发(Touch down之后一定时间(500ms))
		@Override
		public void onLongPress(MotionEvent e) {
			Log.d(TAG, "onLongPress");
		}
	}

}


对整个Activity进行监听

package com.example.touch;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.GestureDetectorCompat;
import android.util.Log;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyActivity2 extends Activity {

	private static final String TAG = "MyActivity2";

	// 用GestureDetectorCompat替换GestureDetector,GestureDetectorCompat兼容的版本较广
	private GestureDetectorCompat mDetector;

	private LinearLayout linearLayout;

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

		initView();

		initDetector();

		// setTouchListener();
	}

	// // 对linearLayout设置手势监听
	// private void setTouchListener() {
	// linearLayout.setOnTouchListener(new OnTouchListener() {
	// @Override
	// public boolean onTouch(View v, MotionEvent event) {
	// mDetector.onTouchEvent(event);
	// return true;
	// }
	// });
	// }

	// 让GestureDetectorCompat来接替处理
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		this.mDetector.onTouchEvent(event);
		// Be sure to call the superclass implementation
		return super.onTouchEvent(event);
	}

	private void initView() {
		linearLayout = (LinearLayout) findViewById(R.id.linearlayout);
	}

	// 初始化手势监听器Detector
	private void initDetector() {
		mDetector = new GestureDetectorCompat(MyActivity2.this,
				new MytGestureListener());
	}

	/**
	 * 手势监听器
	 */
	private class MytGestureListener extends SimpleOnGestureListener {

		// Touch down时触发
		@Override
		public boolean onDown(MotionEvent e) {
			Log.d(TAG, "onDown");
			return super.onDown(e);
		}

		// 在Touch down之后一定时间(115ms)触发
		@Override
		public void onShowPress(MotionEvent e) {
			Log.d(TAG, "onShowPress");
		}

		// 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发
		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			Log.d(TAG, "onSingleTapUp");
			return super.onSingleTapUp(e);
		}

		// 滑动时触发
		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			Log.d(TAG, "onScroll");
			return super.onScroll(e1, e2, distanceX, distanceY);
		}

		// 抛掷
		// 滑动一段距离,up时触发
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			Log.d(TAG, "onFling");
			return super.onFling(e1, e2, velocityX, velocityY);
		}

		// 长按后触发(Touch down之后一定时间(500ms))
		@Override
		public void onLongPress(MotionEvent e) {
			Log.d(TAG, "onLongPress");
		}

		// 双击
		@Override
		public boolean onDoubleTap(MotionEvent e) {
			Log.d(TAG, "onDoubleTap");
			return super.onDoubleTap(e);
		}

	}

}



要点是: 创建一个手势监听器如MyGestureListener继承自SimpleOnGestureListener, 

private class MytGestureListener extends SimpleOnGestureListener 


再用MyGestureListener初始化Detetor对象mDetector,

	// 初始化手势监听器Detector
	private void initDetector() {
		mDetector = new GestureDetectorCompat(MyActivity2.this,
				new MytGestureListener());
	}

然后让mDetector来接替处理手势监听

 // 让GestureDetectorCompat来接替处理
	 @Override
	 public boolean onTouchEvent(MotionEvent event){
	 this.mDetector.onTouchEvent(event);
	 // Be sure to call the superclass implementation
	 return super.onTouchEvent(event);
	 }


三. onFling() 的使用

filing手势在android交互设计中应用非常广泛:电子书的滑动翻页、ListView滑动删除item、滑动解锁等。所以如何检测用户的fling手势是非常重要的。

OnFling的四个参数意思分别为

e1: The first down motion event that started the fling.手势起点的移动事件
e2: The move motion event that triggered the current onFling.当前手势点的移动事件
velocityX: The velocity of this fling measured in pixels per second along the x axis.每秒x轴方向移动的像素
velocityY: The velocity of this fling measured in pixels per second along the y axis.每秒y轴方向移动的像素

说的更简单点就是,鼠标手势相当于一个向量(当然有可能手势是曲线),e1为向量的起点,e2为向量的终点,velocityX为向量水平方向的速度,velocityY为向量垂直方向的速度


if (e1.getX() - e2.getX() > verticalMinDistance && Math.abs(velocityX) > minVelocity)

则上面的语句能知道啥意思了吧,就是说向量的水平长度(滑了有多长)必须大于 verticalMinDistance,并且水平方向速度大于 minVelocity。


onScroll则与之类似,e1为手势起点事件,e2为手势终点事件,distanceX为e1与e2在x轴的差(带正负),distanceY为e1与e2在y轴的差(带正负)


四. Android中的坐标系统
首先明确一下 android中的坐标系统 :屏幕的左上角是坐标系统原点(0,0),原点向右延伸是X轴正方向,原点向下延伸是Y轴正方向


  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值