手势识别兼容Android 1.x和2.x的代码(转载)

流媒体开发先行者 2011-09-08

我们大家都知道,由于Android2.x开始很多API变动比较大新增了一些比如多点触控的支持,对于屏幕触控手势识别中我们需要考虑更多的实现方法,下面是一段兼容Android1.x和2.x的代码,可以让我们的程序兼容几乎99%的Android手机。

一、首先新建一个抽象类判断SDK版本问题

Java代码:

publicabstractclassVersionedGestureDetector{

privatestaticfinalStringTAG="VersionedGestureDetector";

OnGestureListenermListener;

publicstaticVersionedGestureDetectornewInstance(Contextcontext,

OnGestureListenerlistener){

/*设计实例化构造方法,这里Androideoe提示大家目前有3种API的实现方法,我们需要逐一考虑最优的解决方法,以满足高平台更多的功能实现。*/

finalintsdkVersion=Integer.parseInt(Build.VERSION.SDK);

//使用android.os.Build判断APILevel,但需要将字符串转换为整形

VersionedGestureDetectordetector=null;

if(sdkVersion<Build.VERSION_CODES.ECLAIR){

//如果版本小于2.0则使用1.5版本的API,可以兼容1.5和1.6

detector=newCupcakeDetector();

}elseif(sdkVersion<Build.VERSION_CODES.FROYO){

//如果版本小于2.1则使用2.0版本的API,可以兼容2.0,2.0.1和2.1这三个版本

detector=newEclairDetector();

}else{

//否则使用2.2开始的新的触控API

detector=newFroyoDetector(context);

}

Log.d(TAG,"Creatednew"+detector.getClass());//判断最终选择的到底是哪个版本的类

detector.mListener=listener;

returndetector;

}

publicabstractbooleanonTouchEvent(MotionEventev);

//我们需要根据版本决定onTouchEvent的实现

publicinterfaceOnGestureListener{//手势判断接口主要是实现两个方法

publicvoidonDrag(floatdx,floatdy);//拖拽

publicvoidonScale(floatscaleFactor);//缩放

}

privatestaticclassCupcakeDetectorextendsVersionedGestureDetector{

//针对Android1.5和1.6设计的兼容方式

floatmLastTouchX;

floatmLastTouchY;

floatgetActiveX(MotionEventev){//获得当前X坐标

returnev.getX();

}

floatgetActiveY(MotionEventev){//获得当前Y坐标

returnev.getY();

}

booleanshouldDrag(){//是否是拖拽中或者说移动中

returntrue;

}

@Override

publicbooleanonTouchEvent(MotionEventev){//重写onTouchEvent方法

switch(ev.getAction()){

caseMotionEvent.ACTION_DOWN:{//向下

mLastTouchX=getActiveX(ev);

mLastTouchY=getActiveY(ev);

break;

}

caseMotionEvent.ACTION_MOVE:{

/*Androideoe提醒大家,由于1.x时代的API比较简单,很多手势没有封装,我们只能从ACTION_MOVE中根据坐标变化判断手势样式*/

finalfloatx=getActiveX(ev);

finalfloaty=getActiveY(ev);

if(shouldDrag()){

mListener.onDrag(x-mLastTouchX,y-mLastTouchY);//处理拖拽移动

}

mLastTouchX=x;

mLastTouchY=y;

break;

}

}

returntrue;

}

}

privatestaticclassEclairDetectorextendsCupcakeDetector{

//这个是针对Android2.0,2.0.1和2.1提供的解决方法,可以看到有很多多点触控相关API出现

privatestaticfinalintINVALID_POINTER_ID=-1;

privateintmActivePointerId=INVALID_POINTER_ID;

privateintmActivePointerIndex=0;

@Override

floatgetActiveX(MotionEventev){

returnev.getX(mActivePointerIndex);

}

@Override

floatgetActiveY(MotionEventev){

returnev.getY(mActivePointerIndex);

}

@Override

publicbooleanonTouchEvent(MotionEventev){

finalintaction=ev.getAction();

switch(action&MotionEvent.ACTION_MASK){

caseMotionEvent.ACTION_DOWN:

mActivePointerId=ev.getPointerId(0);

break;

caseMotionEvent.ACTION_CANCEL:

caseMotionEvent.ACTION_UP:

mActivePointerId=INVALID_POINTER_ID;

break;

caseMotionEvent.ACTION_POINTER_UP://有个点松开

finalintpointerIndex=(ev.getAction()&MotionEvent.ACTION_POINTER_INDEX_MASK)

>>MotionEvent.ACTION_POINTER_INDEX_SHIFT;

finalintpointerId=ev.getPointerId(pointerIndex);//获取第几个点

if(pointerId==mActivePointerId){

finalintnewPointerIndex=pointerIndex==0?1:0;

mActivePointerId=ev.getPointerId(newPointerIndex);

mLastTouchX=ev.getX(newPointerIndex);//处理第newPointerIndex个点的x位置

mLastTouchY=ev.getY(newPointerIndex);

}

break;

}

mActivePointerIndex=ev.findPointerIndex(mActivePointerId);

returnsuper.onTouchEvent(ev);

}

}

privatestaticclassFroyoDetectorextendsEclairDetector{

//从Android2.2开始可以很好的处理多点触控的缩放问题

privateScaleGestureDetectormDetector;

publicFroyoDetector(Contextcontext){

mDetector=newScaleGestureDetector(context,

newScaleGestureDetector.SimpleOnScaleGestureListener(){

@OverridepublicbooleanonScale(ScaleGestureDetectordetector){

mListener.onScale(detector.getScaleFactor());//根据ScaleGestureDetector.SimpleOnScaleGestureListener这个系统类处理缩放情况通过onScale方法

returntrue;

}

});

}

@Override

booleanshouldDrag(){

return!mDetector.isInProgress();

}

@Override

publicbooleanonTouchEvent(MotionEventev){

mDetector.onTouchEvent(ev);

returnsuper.onTouchEvent(ev);

}

}

}

复制代码

有关调用方法,我们可以自定义一个View,取名为TouchExampleView类,这里来处理触控相关的问题

Java代码:

publicclassTouchExampleViewextendsView{

privateDrawablemIcon;//我们以一个图片为参照物,根据手势控制

privatefloatmPosX;

privatefloatmPosY;

privateVersionedGestureDetectormDetector;

privatefloatmScaleFactor=1.f;//原始缩放比例为1.0

publicTouchExampleView(Contextcontext){

this(context,null,0);

}

publicTouchExampleView(Contextcontext,AttributeSetattrs){

this(context,attrs,0);

}

publicTouchExampleView(Contextcontext,AttributeSetattrs,intdefStyle){//实现我们自定义View的构造

super(context,attrs,defStyle);

mIcon=context.getResources().getDrawable(R.drawable.icon);

mIcon.setBounds(0,0,mIcon.getIntrinsicWidth(),mIcon.getIntrinsicHeight());

mDetector=VersionedGestureDetector.newInstance(context,newGestureCallback());

//实例化刚才的版本自适应手势控制类

}

@Override

publicbooleanonTouchEvent(MotionEventev){

//重写onTouchEvent方法,使用VersionedGestureDetector类得出的数据。

mDetector.onTouchEvent(ev);

returntrue;

}

@Override

publicvoidonDraw(Canvascanvas){//处理自定义View绘制方法

super.onDraw(canvas);

canvas.save();

canvas.translate(mPosX,mPosY);//进行平移操作,根据mPosX和mPosY坐标

canvas.scale(mScaleFactor,mScaleFactor);//进行缩放操作,参数就是刚才定义的float类型的缩放比例

mIcon.draw(canvas);//直接绘制图片变化到画布中

canvas.restore();

}

privateclassGestureCallbackimplementsVersionedGestureDetector.OnGestureListener{

publicvoidonDrag(floatdx,floatdy){

//这里Android123提示大家在2.2中这个回调方法将可以支持拖拽的坐标处理

mPosX+=dx;

mPosY+=dy;

invalidate();

}

publicvoidonScale(floatscaleFactor){

mScaleFactor*=scaleFactor;//缩放控制

mScaleFactor=Math.max(0.1f,Math.min(mScaleFactor,5.0f));

//限制最小缩放比例为1.0最大为5.0倍数

invalidate();

}

}

}

复制代码

有关调用我们的自定义的TouchExampleView可以在Activity的onCreate方法中加入以下代码

Java代码:

TouchExampleViewview=newTouchExampleView(this);

view.setLayoutParams(newViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,

ViewGroup.LayoutParams.MATCH_PARENT));

setContentView(view);//替换掉原始的res.layout.main

复制代码

最后Androideoe需要给大家说明的是使用本例子,直接使用Android2.2的SDK创建工程,即APILevel为8,发布时在androidmanifest.xml中加入uses-sdkandroid:minSdkVersion="3"android:targetSdkVersion="8"这句可以兼容从Android1.5到2.2的版本,有关2.3中新增的一个可以处理5个或5个以上的多点触控增强类Android开发网将在以后的时间中介绍。

转载出自:http://www.apkbus.com/forum.php?mod=viewthread&tid=848

相关推荐