这里有新鲜出炉的精品教程,程序狗速度看过来!
Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用“安卓”或“安致”。
本文主要介绍Android 的触摸事件,这里整理了详细的资料,并附代码示例,希望能帮助到有需要的小伙伴
由于触摸(Touch)而触发的事件
Android的事件:onClick, onScroll,onFling等等,都是由许多个Touch组成的。其中Touch的第一个状态肯定是ACTION_DOWN,表示按下了屏幕。之后,touch将会有后续事件,可能是:
ACTION_MOVE //表示为移动手势
ACTION_UP //表示为离开屏幕
ACTION_CANCEL //表示取消手势,不会由用户产生,而是由程序产生的
一个Action_DOWN, n个ACTION_MOVE, 1个ACTION_UP,就构成了Android中众多的事件。
对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。
而方法onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递。
touch事件在onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。返回值为true表示事件被正确接收和处理了,返回值为false表示事件没有被处理,将继续传递下去。
ACTION_DOWN事件会传到某个ViewGroup类的onInterceptTouchEvent,如果返回false,则DOWN事件继续向子ViewGroup类的onInterceptTouchEvent传递,如果子View不是ViewGroup类的控件,则传递给它的onTouchEvent。
如果onInterceptTouchEvent返回了true,则DOWN事件传递给它的onTouchEvent,不再继续传递,并且之后的后续事件也都传递给它的onTouchEvent。
如果某View的onTouchEvent返回了false,则DOWN事件继续向其父ViewGroup类的onTouchEvent传递;如果返回了true,则后续事件会直接传递给其onTouchEvent继续处理。(后续事件只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent)
总结一下就是:onInterceptTouchEvent可以接受到所有的Touch事件,而onTouchEvent则不一定。
对于android 自定义控件的事件 android提供了一个GestureDetector的类和GestureDetector.OnGestureListener的接口来判断用户在界面上做出怎么样的动作。
Android里有两个类
android.view.GestureDetector
android.view.GestureDetector.SimpleOnGestureListener
(另外android.widget.Gallery好像是更牛x的OnGestureListener )
1)新建一个类继承SimpleOnGestureListener,HahaGestureDetectorListener
可以实现以下event事件。
boolean onDoubleTap(MotionEvent e)
解释:双击的第二下Touch down时触发
boolean onDoubleTapEvent(MotionEvent e)
解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
boolean onDown(MotionEvent e)
解释:Touch down时触发
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)
解释:Touch了滑动一点距离后,up时触发。
void onLongPress(MotionEvent e)
解释:Touch了不移动一直Touch down时触发
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY)
解释:Touch了滑动时触发。
void onShowPress(MotionEvent e)
解释:Touch了还没有滑动时触发
(与onDown,onLongPress比较
onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
)
boolean onSingleTapConfirmed(MotionEvent e)
boolean onSingleTapUp(MotionEvent e)
解释:上面这两个函数都是在touchdown后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
点击一下非常快的(不滑动)Touchup:
onDown->onSingleTapUp->onSingleTapConfirmed
点击一下稍微慢点的(不滑动)Touchup:
onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed
- publicclassGestureActivityextendsActivityimplementsOnTouchListener,
- OnGestureListener {
- GestureDetector detector;
- publicGestureActivity() {
- detector = new GestureDetector(this);
- }
- publicvoidonCreate(BundlesavedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- TextView tv = (TextView) findViewById(R.id.TextView001);
- //设置tv的监听器
- tv.setOnTouchListener(this);
- tv.setFocusable(true);
- //必须,view才能够处理不同于Tap(轻触)的hold
- tv.setClickable(true);
- tv.setLongClickable(true);
- detector.setIsLongpressEnabled(true);
- }
- publicbooleanonTouch(View v, MotionEvent event) {
- returndetector.onTouchEvent(event);
- }
- // 用户轻触触摸屏,由1个MotionEventACTION_DOWN触发
- publicbooleanonDown(MotionEventarg0) {
- Log.i("MyGesture", "onDown");
- Toast.makeText(this, "onDown", Toast.LENGTH_SHORT).show();
- returntrue;
- }
- publicvoidonShowPress(MotionEvent e) {
- Log.i("MyGesture", "onShowPress");
- Toast.makeText(this, "onShowPress", Toast.LENGTH_SHORT).show();
- }
- // 用户(轻触触摸屏后)松开,由一个1个MotionEventACTION_UP触发
- publicbooleanonSingleTapUp(MotionEvent e) {
- Log.i("MyGesture", "onSingleTapUp");
- Toast.makeText(this, "onSingleTapUp", Toast.LENGTH_SHORT).show();
- returntrue;
- }
- // 用户按下触摸屏、快速移动后松开,由1个MotionEventACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发
- publicbooleanonFling(MotionEvente1, MotionEvent e2, float velocityX, float velocityY) {
- Log.i("MyGesture", "onFling");
- // 参数解释:
- // e1:第1个ACTION_DOWNMotionEvent
- // e2:最后一个ACTION_MOVEMotionEvent
- // velocityX:X轴上的移动速度,像素/秒
- // velocityY:Y轴上的移动速度,像素/秒
- // 触发条件 :
- // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
- finalintFLING_MIN_DISTANCE = 100,
- FLING_MIN_VELOCITY = 200;
- if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Flingleft
- Log.i("MyGesture", "Fling left");
- Toast.makeText(this, "FlingLeft", Toast.LENGTH_SHORT).show();
- }
- elseif(e2.getX() - e1.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Flingright
- Log.i("MyGesture", "Fling right");
- Toast.makeText(this, "FlingRight", Toast.LENGTH_SHORT).show();
- }
- elseif(e2.getY() - e1.getY() > FLING_MIN_DISTANCE && Math.abs(velocityY) > FLING_MIN_VELOCITY) {
- // Flingdown
- Log.i("MyGesture", "Fling down");
- Toast.makeText(this, "Flingdown", Toast.LENGTH_SHORT).show();
- }
- elseif(e1.getY() - e2.getY() > FLING_MIN_DISTANCE && Math.abs(velocityY) > FLING_MIN_VELOCITY) {
- // Fling up
- Log.i("MyGesture", "Fling up");
- Toast.makeText(this, "Flingup", Toast.LENGTH_SHORT).show();
- }
- returnfalse;
- }
- // 用户按下触摸屏,并拖动,由1个MotionEventACTION_DOWN, 多个ACTION_MOVE触发
- publicbooleanonScroll(MotionEvente1, MotionEvent e2, float distanceX, float distanceY) {
- Log.i("MyGesture", "onScroll");
- Toast.makeText(this, "onScroll", Toast.LENGTH_LONG).show();
- returntrue;
- }
- // 用户长按触摸屏,由多个MotionEventACTION_DOWN触发
- publicvoidonLongPress(MotionEvent e) {
- Log.i("MyGesture", "onLongPress");
- Toast.makeText(this, "onLongPress", Toast.LENGTH_LONG).show();
- }
- }
2)在view的新建一个GestureDetector的对象。
构造函数里
gestureDetector = new GestureDetector(newHahaGestureDetectorListener());
然后在View的onTouchEvent里以下这样用,就可以在刚才1)弄的事件里写自己的代码了。
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- gestureDetector.onTouchEvent(event);
- }
- mTouchListener = new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // TODO Auto-generated method stub
- float x =event.getXPrecision()*event.getX()+event.getX();
- float y =event.getYPrecision()*event.getY()+event.getY();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- break;
- case MotionEvent.ACTION_MOVE:
- mTouchTimes++;
- if (mTouchTimes > TOUCH_TIMES) {
- // 根据方向计算角度
- if (mCurrentOrientation==DeviceOrientation.Landscape) {
- mAngle = Math.toDegrees(Math.atan2(y - 480 / 2, x))+90;
- } else {
- mAngle = -Math.toDegrees(Math.atan2(y - 480 / 2,320-x))+90;
- }
- Log.w("angle", "mangle:"+mAngle);
- }
- break;
- case MotionEvent.ACTION_UP:
- if (mTouchTimes > TOUCH_TIMES) {
- } else {
- }
- mTouchTimes = 0;
- break;
- default:
- break;
- }
- return true;
- }
- };
- mView.setOnTouchListener(mTouchListener);
来源: http://www.phperz.com/article/17/0918/348128.html