最后更新:2012-03-20html
参考自:《Android移动开发一本就够》java
说在前面,很早时,android就开始有支持单点手势(单点触控),到android2.2开始支持多点触控.android
不一样的动做序列合起来表示不一样的手势。好比Fling手势包括三个过程:将手指按触在屏幕上,而后快速扫过,最后api
抬起手指,而且在抬起手指仍然在运动(也就是说抬起手指前,运动的速度并不会减小).每个步操做都会触发相应的事件。app
在View控件内,开发人员能够像处理普通的单击事件时使用setOnClickListener()和setOnLongClickListener()ide
方法同样处理手势。onTouchEvent()回调方法用于探测View区域内的用户动做。学习
onTouchEvent()回调方法只接收一个参数。MotionEvent对象。MotionEvent对象包含在View内触发的全部类型动做动画
的细节,经过收集和分析连续的MotionEvent对象,开发人员能够肯定产生了何种手势。你可使用MotionEvent数据this
来识别的探测任何你能想像的手势。不过你也可使用Android SDK 内置的手势探测器来探测普通的用户动做。idea
android目前拥有两个不一样的类用于手势探测。
(1) GestureDetector类能够用于探测通常的单点触控手势。
(2) ScaleGestureDetector能够用来探测多点缩放操做手势。
除了普通的方向性手势,你还可使用API level 4中引入的android.gesture包中的GestureOverlayView来识别命令手势。
下面主要是处理普通单点触控手势
API level 1中引入的GestureDetector类能够用来探测单个手势。GestureDetector类所支持的单指手势包括如下几种。
onDown:当用户第一次按触屏幕时触发。
onShowPress:当用户按触屏幕,而且在抬起或移动手指以前触发:用于显示显示地指示按触事件确已探测到。
onSingleTapUp:做为单击(sinlge-tap)事件的一部分,在用户从触屏上抬起手指(使用抬起MotionEvent)时触发。
onSingleTabConfirmed:单击事件发生时调用。
onDoubleTab:双击(double-tap)事件发生时调用。
onDoubleTabEvent:在任何双击手势发生时调用,包括按下(down),移动,或抬起(up)MotionEvent.
onLongPress:与onSingleTapUp相似,但只在用户保持按触状态且不移动必定时间,而且不是标准的单击操做时调用。
onScroll:用户按下手指而且匀速移动手指后,在抬起手指前调用。一般也称为“拖曳”(dragging).
onFling:在用户按下而且加速移动手指后,在抬起手指前调用,一般也称为"拂动(flick)手势。
提示:你可使用GestureDetector.SimpleOnGestureListener类来监听由GestureDetector识别的任何手势。
实例:在Android中实现图片左右滑动效果。
参考来自:
http://www.cnblogs.com/hanyonglu/archive/2012/02/13/2349827.html
原文比较详细,在此不转。注意的一点就是,为了避免带那些不用的方法,能够继承SimpleOnGestureListener类。
说一下,我我的的感觉。
1.受到一些网上不正确的文章,实习OnTouchListener了。
结果,原本应该重写GestureDetector.OnGestureListener接口的
onTouchEvent方法时,实现了onTouch()方法,害我总是看不到效果,这里弄,那里查,结果,找了开始那本书学习。
系统学习以后,而后我看源代码。发现了GestureDetector类这样的javadoc:
/** * To use this class: * <ul> * <li>Create an instance of the {@code GestureDetector} for your {@link View} * <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call * {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback * will be executed when the events occur. * </ul> **/
上面那个ensure让我以为应该检查下是否是实现了。而后,结果就出来了。哈哈。太不当心了。
关于判断手势效果的代码:
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT); if (e1.getX() - e2.getX() > 120) { this.mFlipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in)); this.mFlipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out)); this.mFlipper.showNext(); return true; }
1.上面触发事件时,我写有Toast提醒代码,可是实际上,用户看不到。
2.第二 上面判断手势距离要求120px有点大长了。
下面学习下其中起到关键做用的另一个类。ViewFlipper.
ViewFlipper的类继承关系以下:
ViewFlipper->ViewAnimator->FrameLayout->ViewGroup->View->Object
看一下类描述:(中文翻译来自Android中文翻译组)
/** * Simple {@link ViewAnimator} that will animate between two or more views * that have been added to it. Only one child is shown at a time. If * requested, can automatically flip between each child at a regular interval. * 被添加到ViewFlipper中的两个或两个以上的视图之间将执行一个简单的ViewAnimator动画。
一次仅能显示一个子视图。若是须要,能够设置间隔时间使子视图像幻灯片同样自动显示。
(译者注:com.example.android.apis.view/Animation_2.java包含该类示例程序) * @attr ref android.R.styleable#ViewFlipper_flipInterval * @attr ref android.R.styleable#ViewFlipper_autoStart */
通过使用SimpleOnGestureListener类后的所有Java代码以下:
package me.banxi.slideapp; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.Toast; import android.widget.ViewFlipper; public class SlideAndGestureActivity extends Activity { private ViewFlipper mFlipper; private GestureDetector mDetector; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.slide); mDetector = new GestureDetector(getApplicationContext(),new FlingListener()); mFlipper = (ViewFlipper )findViewById(R.id.viewFlipper1); mFlipper.addView(addTextView(R.drawable.one)); mFlipper.addView(addTextView(R.drawable.two)); mFlipper.addView(addTextView(R.drawable.three)); mFlipper.addView(addTextView(R.drawable.four)); mFlipper.addView(addTextView(R.drawable.five)); } private View addTextView(int resId){ ImageView view = new ImageView(this); view.setImageResource(resId); return view; } @Override public boolean onTouchEvent(MotionEvent event) { return mDetector.onTouchEvent(event); } private class FlingListener extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { String msg = "e1:"+e1.getX()+","+e1.getY()+"e2:"+e2.getX()+","+e2.getY(); Log.i("MotionSlide", msg); if (e1.getX() - e2.getX() > 120) { mFlipper.setInAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_in)); mFlipper.setOutAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_left_out)); mFlipper.showNext(); return true; } else if (e1.getX() - e2.getX() < -120) { mFlipper.setInAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_in)); mFlipper.setOutAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.push_right_out)); mFlipper.showPrevious(); return true; } return false; } } }
在实际的项目开发中会遇到这样同样问题。
好比。上面 例子添加的ImageView默认也许不处理事件。因此 能够 正常的滑动。
可是在个人实际的开发中,的发现如ViewFlipper上面有一个GridView,GridView上面排列有Button.而后滑动手势
的事件就不会传播到ViewFlipper中去啊。因而我开始是在GridView上面 设置 一个margin
在margin区域里滑动事件 就会传递给ViwFlipper。(严格来讲应该是mDetecotor.onTouchEvent()中去。
而后我就在想这个事件 传播的问题,而后我想到由于其实主要调用mDetecotor的时候,
也是在Activity中的OnTouchEvent(MotionEvent)方法 中。
中将这个MotionEvent事件以这样return mDetector.onTouchEvent(event)方法处理返回 。
因而 想在button中事件中的ACTION_MOVE中也调用mDetector.OnTouchEvent()
可是结果 不行。后来我就不区分ACTION_MOVE等等了。
因而,最后,我在对button和gridView作了以下处理。
button.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mDetector.onTouchEvent(event); } });
gridView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mDetector.onTouchEvent(event); } });我想,由于Fliing这样事件不只仅是ACTION_MOVE他还有开始的OnDown等等一系列事件组合起来的。