Android开发 Android手势

转载 2015年11月19日 22:25:34

之前做的App是完全没有任何手势支持的,对于现在的程序来说,如果没有一些手势的支持,感觉实在是有点落后了,支持手势的App才叫cool。于是在这次重新搭建ifood for android框架的同时下决心让自己的App完全支持手势。下面就来看下自己实现的一个全局滑动切换窗口的例子。

在android系统中,手势的识别是通过 GestureDetector.OnGestureListener接口来实现的。如果要自定义手势需要重写这个接口里的一些方法,废话不多说,下面上代码:

自定义的一个GestureLisntener:

MyGestureListener.java
public class MyGestureListener implements OnGestureListener {

	static final String TAG = "MyGestureListener";

	private static final int SWIPE_MAX_OFF_PATH = 100;
	private static final int SWIPE_MIN_DISTANCE = 100;
	private static final int SWIPE_THRESHOLD_VELOCITY = 100;
	
	public Context context;
	
	public MyGestureListener(Context context) {
		this.context = context;
	}

	@Override
	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onShowPress(MotionEvent e) {
		// TODO Auto-generated method stub
		Log.e(TAG, "onShowPress");
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
		// TODO Auto-generated method stub
		Log.e(TAG, "onLongPress");
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
			return false;

		if ((e1.getX() - e2.getX()) > SWIPE_MIN_DISTANCE
				&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
			Log.e(TAG, "onFling left");

		} else if ((e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE
				&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
			Log.e(TAG, "onFling right");
			((Activity) context).finish();
			
		}
		return true;
	}

}

在这个类中的onFling()方法中从左向右滑动时实现了界面的切换,如果有更复杂的手势支持,同样可以在这个基类中进行添加。

接下来新建一个GestureActivity实现Gesture滑动切换界面,让支持手势的Activity继承它,这样就继承了它的手势支持功能,提高代码复用。

GestureActivity.java
public class GestureActivity extends ActivityBase {

	MyGestureListener listener = new MyGestureListener(this);
	protected GestureDetector gestureDetector = new GestureDetector(listener);
	
	public boolean onTouchEvent(MotionEvent event) {
        if (gestureDetector.onTouchEvent(event))
            return true;
        else  
            return false;
    }
	
}

这样就实现了一个简单的滑动切换页面的框架,如果想支持更多的手势,只需要重写MyGestureListener的方法就可以了。

不过不要高兴的太早,在一般的Activity手势支持是正常的,可是碰到一些包含ScrollView或者ListView的Activity时,手势就不相应了。原因是因为这些滑动的组件本身就已经具有了手势的支持,这样就会产生了冲突,导致自定义的手势没有被识别到。google了很久,似乎也没个具体的方法,后来看到说用dispatchTouchEvent(MotionEvent ev) 的方法,果然可以。于是在GestureActivity里就多了这样一个方法:

public boolean dispatchTouchEvent(MotionEvent ev) {
    gestureDetector.onTouchEvent(ev);
    return super.dispatchTouchEvent(ev);
}

此时再试一下,果然所有Activity都实现了自定义的手势事件。但是为什么加上这个方法就可以了呢,必须要搞明白。

android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。

一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE…->ACTION_MOVE->ACTION_UP

当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?答案是:不一定。

android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:

1.public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent

2.public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent

3.public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent

当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由 dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。

看到这终于清楚了上面的疑问,dispatchTouchEvent()方法直接将触摸事件交给了gestureDetector的触摸事件,这样就解决了冲突问题。

Android手势密码实现方案

一、大致界面介绍: 图1 图2 图3 图4 图1:手势密码绘制界面 【主要是绘制上方的9个提示图标和9个宫格密码图标】 图2:设置手...
  • sdjianfei
  • sdjianfei
  • 2016年04月27日 15:55
  • 6325

Android 手势锁的实现 让自己的应用更加安全吧

今天偶遇以github上gesturelock关于手势锁的一个例子(有兴趣的去搜索下看看),于是下载下来研究,无奈基本没有注释,代码上存在一些问题(当设置gravity=center_vertical...
  • lmj623565791
  • lmj623565791
  • 2014年07月01日 23:48
  • 38798

Android手势识别详解

一、使用GestureDetector进行手势识别 手势交互过程(原理): 1、触屏一刹那,触发MotionEvent事件 2、被OnTouchListener监听,在onTouch()中获得Moti...
  • c19344881x
  • c19344881x
  • 2015年02月26日 15:22
  • 2301

招财进宝手势锁,Android手势密码的实现

这几个月都是在做招财进宝项目,一个理财下载地址:http://8.shengpay.com/。招财进宝手势锁,Android手势密码的实现。...
  • wulianghuan
  • wulianghuan
  • 2014年11月03日 17:01
  • 21184

android view手势冲突的通用解决方法

android手势事件的冲突跟点击事件的分发过程息息相关,由三个重要的方法来共同完成,分别是:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent...
  • jinsiryan
  • jinsiryan
  • 2016年05月18日 21:41
  • 611

Android之——根据手势简单缩放图片

很久没有发表关于Android的文章了,今天,给大家带来一篇如何根据手势简单缩放图片的文章。 一、原理 老样子,我们还是先讲讲原理性的东东,很简单,当手指触摸屏幕图片时,记录下当时手指的坐标点;手指滑...
  • l1028386804
  • l1028386804
  • 2015年11月26日 22:38
  • 2627

Android应用 手势密码的实现(三)

本文基于Hongyang大神的博客:http://blog.csdn.net/lmj623565791/article/details/36236113 转载请注明来源:http://blog.cs...
  • u013258802
  • u013258802
  • 2016年11月07日 13:52
  • 2605

【Android】 从头搭建视频播放器(3)——手势检测 & 控制

1、介绍了手势检测的方法; 2、介绍了屏幕亮度 & 媒体音量的调节; 3、实现了一个 MediaPlayerGestureController。...
  • ZhangYafengCPP
  • ZhangYafengCPP
  • 2015年09月25日 17:35
  • 2663

Android 手势监听学习总结

android的简单手势监听一般用onTouchListner接口,复杂手势监听一般用Detector来接替onTouch的处理。 手势监听后的处理涉及android坐标系统的问题。 多点触点则一般用...
  • guige_csdn
  • guige_csdn
  • 2015年08月29日 21:03
  • 2106

android开发步步为营之3:自定义控件之手势签名

在Android中,我们常用的控件,例如按钮(Button)、文本框(TextView),可编辑文本框(EditText),列表框(ListView),复选框(CheckBox),单选框(RadioB...
  • figo0423
  • figo0423
  • 2013年05月04日 18:06
  • 1540
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android开发 Android手势
举报原因:
原因补充:

(最多只允许输入30个字)