说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

手势识别兼容Android 1.x和2.x的代码

HTML文档下载 WORD文档下载 PDF文档下载
手势识别兼容Android 1.x和2.x的代码

作者:Android开发网


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

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

 public abstract class VersionedGestureDetector {
    private static final String TAG = "VersionedGestureDetector";

    OnGestureListener mListener;

    public static VersionedGestureDetector newInstance(Context context,
            OnGestureListener listener) {  //设计实例化构造方法,这里Android123提示大家目前有3种API的实现方法,我们需要逐一考虑最优的解决方法,以满足高平台更多的功能实现。

        final int sdkVersion = Integer.parseInt(Build.VERSION.SDK); //使用android.os.Build判断API Level,但需要将字符串转换为整形
        VersionedGestureDetector detector = null;
        if (sdkVersion < Build.VERSION_CODES.ECLAIR) { //如果版本小于2.0则使用1.5版本的API,可以兼容1.5和1.6
            detector = new CupcakeDetector();
        } else if (sdkVersion < Build.VERSION_CODES.FROYO) { //如果版本小于2.1则使用2.0版本的API,可以兼容2.0,2.0.1和2.1这三个版本
            detector = new EclairDetector();
        } else {  //否则使用2.2开始的新的触控API

            detector = new FroyoDetector(context);
        }

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

        return detector;
    }

    public abstract boolean onTouchEvent(MotionEvent ev); //我们需要根据版本决定onTouchEvent的实现

    public interface OnGestureListener { //手势判断接口主要是实现两个方法
        public void onDrag(float dx, float dy);  //拖拽
        public void onScale(float scaleFactor); //缩放
    }

    private static class CupcakeDetector extends VersionedGestureDetector { //针对Android 1.5和1.6设计的兼容方式
        float mLastTouchX;
        float mLastTouchY;

        float getActiveX(MotionEvent ev) { //获得当前X坐标
            return ev.getX();
        }

        float getActiveY(MotionEvent ev) { //获得当前Y坐标
            return ev.getY();
        }

        boolean shouldDrag() { //是否是拖拽中或者说移动中
            return true;
        }

        @Override
        public boolean onTouchEvent(MotionEvent ev) { //重写onTouchEvent方法
            switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN: {  //向下
                mLastTouchX = getActiveX(ev);
                mLastTouchY = getActiveY(ev);
                break;
            }
            case MotionEvent.ACTION_MOVE: { //Android开发网提醒大家,由于1.x时代的API比较简单,很多手势没有封装,我们只能从ACTION_MOVE中根据坐标变化判断手势样式
                final float x = getActiveX(ev);
                final float y = getActiveY(ev);

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

                mLastTouchX = x;
                mLastTouchY = y;
                break;
            }
            }
            return true;
        }
    }

    private static class EclairDetector extends CupcakeDetector { //这个是针对Android 2.0,2.0.1和2.1提供的解决方法,可以看到有很多多点触控相关API出现
        private static final int INVALID_POINTER_ID = -1;
        private int mActivePointerId = INVALID_POINTER_ID;
        private int mActivePointerIndex = 0;

        @Override
        float getActiveX(MotionEvent ev) {
            return ev.getX(mActivePointerIndex);
        }

        @Override
        float getActiveY(MotionEvent ev) {
            return ev.getY(mActivePointerIndex);
        }

        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            final int action = ev.getAction();
            switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mActivePointerId = ev.getPointerId(0);
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                mActivePointerId = INVALID_POINTER_ID;
                break;
            case MotionEvent.ACTION_POINTER_UP: //有个点松开
                final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                final int pointerId = ev.getPointerId(pointerIndex); //获取第几个点
                if (pointerId == mActivePointerId) {
                    final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                    mActivePointerId = ev.getPointerId(newPointerIndex);
                    mLastTouchX = ev.getX(newPointerIndex); //处理第newPointerIndex个点的x位置
                    mLastTouchY = ev.getY(newPointerIndex);
                }
                break;
            }

            mActivePointerIndex = ev.findPointerIndex(mActivePointerId);
            return super.onTouchEvent(ev);
        }
    }

    private static class FroyoDetector extends EclairDetector { //从Android 2.2开始可以很好的处理多点触控的缩放问题
        private ScaleGestureDetector mDetector;

        public FroyoDetector(Context context) {
            mDetector = new ScaleGestureDetector(context,
                    new ScaleGestureDetector.SimpleOnScaleGestureListener() {
                @Override public boolean onScale(ScaleGestureDetector detector) {
                    mListener.onScale(detector.getScaleFactor()); //根据 ScaleGestureDetector.SimpleOnScaleGestureListener这个系统类处理缩放情况通过onScale方法
                    return true;
                }
            });
        }

        @Override
        boolean shouldDrag() {
            return !mDetector.isInProgress();
        }

        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            mDetector.onTouchEvent(ev);
            return super.onTouchEvent(ev);
        }
    }
}

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

public class TouchExampleView extends View {
    private Drawable mIcon; //我们以一个图片为参照物,根据手势控制
    private float mPosX;
    private float mPosY;

    private VersionedGestureDetector mDetector;
    private float mScaleFactor = 1.f; //原始缩放比例为1.0

    public TouchExampleView(Context context) {
        this(context, null, 0);
    }

    public TouchExampleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TouchExampleView(Context context, AttributeSet attrs, int defStyle) { //实现我们自定义View的构造
        super(context, attrs, defStyle);
        mIcon = context.getResources().getDrawable(R.drawable.icon);
        mIcon.setBounds(0, 0, mIcon.getIntrinsicWidth(), mIcon.getIntrinsicHeight());

        mDetector = VersionedGestureDetector.newInstance(context, new GestureCallback()); //实例化刚才的版本自适应手势控制类
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) { //重写onTouchEvent方法,使用VersionedGestureDetector类得出的数据。
        mDetector.onTouchEvent(ev);
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) { //处理自定义View绘制方法
        super.onDraw(canvas);

        canvas.save();
        canvas.translate(mPosX, mPosY); //进行平移操作,根据mPosX和mPosY坐标
        canvas.scale(mScaleFactor, mScaleFactor); //进行缩放操作,参数就是刚才定义的float类型的缩放比例
        mIcon.draw(canvas); //直接绘制图片变化到画布中
        canvas.restore();
    }

    private class GestureCallback implements VersionedGestureDetector.OnGestureListener {
        public void onDrag(float dx, float dy) { //这里Android123提示大家在2.2中这个回调方法将可以支持拖拽的坐标处理
            mPosX += dx;
            mPosY += dy;
            invalidate();
        }

        public void onScale(float scaleFactor) {
            mScaleFactor *= scaleFactor; //缩放控制

            mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); //限制最小缩放比例为1.0最大为5.0倍数

            invalidate();
        }
    }
}

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

     TouchExampleView view = new TouchExampleView(this);
     view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
      ViewGroup.LayoutParams.MATCH_PARENT));

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

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

Twitter的系统编程 百度高通达成合作 为Android终端提供云服务 EasyHadoop技术沙龙在北京、广州两地齐发 CloudStack技术沙龙:committer李学辉及中航信分享 思科为什么愿意花12亿美元收购云计算网络初创公司Meraki? 谷歌有麻烦了!联邦贸易委员会正调查其搜索业务 当数据中心遭遇污水 微软新能源数据中心的诞生 2012vForum:更加注重开发者 腾讯赵伟:Hive在腾讯分布式数据仓库的实践 Apple将在2013年启动香港数据中心的建设 顶级域名扩张受阻:ICANN透露部分域名存争议 硅谷创业教父Paul Graham:如何获得创业好点子? GDC2012特别报道:中西方游戏开发思想在这里融合 应用示例和对象是编程的未来吗? 为什么2012年HTML5发展远未达预期 当程序不再工作时,程序员说 独立游戏开发者易犯的9大致命错误 “Do Not Track”的前世今生 《Warcraft是怎样炼成的(三)》:从Demo到游戏 无限强大的超级马里奥AI 以Google第二代数据库产品MegaStore为理论模式 探索HBase系统 传Google明年推Chrome OS触摸屏上网本 下载自己过去的Tweets?用户准备好了吗? 微软任命研究部门新副总裁 负责北京等实验室 欧朋首席标准官:HTML5将在2014年成熟 开发利器:对游戏开发者最具价值的5类iOS应用 专访前IE浏览器内核研发工程师,带你深入了解IE10 Windows 8市场接纳速度慢于Windows 7 别只看下载量!“用户留存率”才是关键! 预计2020年出现百亿亿次级超级计算机 Google数据中心PUE的秘密 我的msdn怎么了! C语言 在局域网中怎么才能使linux访问Internet? 我要问一个烂问题哈哈! 打印 华泰贝通,北京创智你去那家? 学习vc++,我离不开书,或者说了开书后,我什末也做不了,我该如何继续学习? 华泰贝通,北京创智你去那家? 简单问题:PB6.5中调用SQLSERVER的procedure! 打印 怎么去掉单文档视图中的菜单 华泰贝通,北京创智你去那家? 哪里有IDE技术规范的中文资料下载? 华泰贝通,北京创智你去那家? 哪里有IDE技术规范的中文资料下载? 如何把从文本登录该为Xwindow登录方式呢? 华泰贝通,北京创智你去那家? /***VC 6.0 的两个操作*/ 有关编译错误,百思不得其解!!(菜鸟那分) 怎么实现程序的换肤功能呢?? 怎样实现左连接(left outer join),右连接 这个网站制作费能值多少?? 怎样处理异质链表? 报表打开的时候缺省为最大化状态,怎么样为设计时候状态? 除了梅尔森式外,还有哪个比较好用的质数生成式?(要100位左右的) 如何在英文版的WINDOWS2k上输入中文? 为了提高大家专家分的质量,希望大家不要再散分了! 我在sun的网站上下了jdk1.4,请问怎么把JBuilder6的jdk升级到jdk1.4? 大家给推荐windows程序,sdk编程的入门好书(不是MFC的)言者有分 我在http://soft.jx163.com/上下载了JBuilder7但不知道怎样得到注册码 有没有其它免费空间(要支持ASP的) 为什么每次打开水晶报表都要求输入oricle数据库的密码和用户名,这些可以在程序里面完成吗?可以再crystalreportviewer空间里面实现翻页 请解释一下ASSERT()函数的作用 informix问题,紧急求救 求救!高手请进来 求助:build winsock 程序时出现 link 错误。 怎样能够将source safe link 像VC哪样集成到自己的应用程序? 关于用ASP+JMAIL开发一个像网易那种类似功能邮件系统的可行性!!!!大家来讨论一下!!! SQL Server7.0的ODBC驱动哪里有(不想安装客户端) 怎样将form中的值加入到数据库中 这个程序是在哪里和在什么时候执行的???? 急啊,我第一次用SQL SERVER,需要把ID号的属性定义为可自动编号,可是找不到相应的字符,可不可一帮帮我? 怎样使DLG的CLOSE(X)按钮变灰? ???? 关于managementserver的问题 b/s中的中文问题 关于udp发送的一些疑惑,请指点,up,gz也给分?(udp) pb的连编问题 对不起大家,内疚ing... 我的专家分怎么忽高忽低?谁给我解释解释! 各位老大,这种报表如何做啊?很急的啊!!!!!!!! 是否所有含碘的物质都能使淀粉溶液变蓝 【高一化学】三氧化硫是什么状态的?是固体还是气体?两种都有?两种都有刺激性气味? 黄金分割线的数字是怎么算出来的 孚县草原火灾是怎么这么猛消防员没有有效的自救措施? 在三角形ABC中AD垂直于BC,ae平分角BAC,角B=80度,角C=46度,你能发现角DAE与角B角C的关系吗在三角形ABC中AD垂直于BC,ae平分角BAC,角B=80度,角C=46度,你能发现角DAE与角B角C的关系吗?是要关系,用文 小红的语文和数学测试的总分是188分,如果把语文分数减去一半,两门功课总分便是142分, 草原火灾属于自然灾害吗 己知,如图,在三角形ABC中,<BAC=80度,AD垂直于BC于D,AE平分<DAC,<B=60度.(1)求<AEC的度数.(2)想一想,还有其它的求法吗?写出你的思考. 1、一个平行四边形的周长是7.2分米,相邻的两边长度比是4:5,长边所对应的高是25厘米.该平行四边形的面积是多少?2、某职工大学去年有学生2700人.今年,男生人数比去年增加9%,女生人数比去年 我是男的,为什么十个手指都是簸箕,代表什么? 甲.乙.丙三人各拿一只水桶在自来水水笼头前等候打水,把他们打水所需的时间分为4分.3分6分.现在只有一个水龙头可以用.问怎样安排这三个人打水顺序,才能使他们总的等候时间最短? 2008年的9月6日6星期六问2009年的9月7日是星期几?答案是星期一,请问怎么用逻辑思维解出来? 手指头都是簸箕代表什么呀? 如图,已知三角形abc中,角bap=角cap,ab加bp=ac.求证:角b=2角c 四边形ABCD中,DC平行AB,以AD,AC为边做平行四边形ABCD,延长DC交EB与F 求EF等于FB图是这样的,四边形ADFB中,C为DF上一点,连接AC,BC,以DF为边做三角形DFE,连接CEACED为平行四边形 我急用 希望快点回答把步 如图所示,在梯形ABCD中,∠1=90°,AB=2,CD=1,BC=3,E是AD中点,EC和EB的位置关系,说明理由.3种方法及以上! 三角形ABC的外角∠ACD的平分线CP与内角∠ABC平分线BP交于点P,若∠BPC=40度,求∠CAP我想问一条貌似很简单的数学题 乙炔气瓶瓶体是否应该套减震圈 在梯形abcd中 AB‖CD,∠A=90,AB=2,BC=3,CD=1,E是AD中点,是判断ED与EB的位置关系,并写出推理过程.详细解答过程 如图,三角形ABC的外角∠ACD的平分线CP与内角∠ABC平分线BP交于点P,若∠PBC=40°,则∠CAP=___如图,三角形abc的外角角ACD的平分线CP与内角角ABC平分线BP交于点P若 天然气瓶可以用多少年 在梯形ABCD中,AB平行CD,角A等于90°,AB等于2,BC等于3,CD等于1,E是AD的中点,试判断EC的位置关系,并写出推理过程!我知道是垂直, 压强到底是什么!我实在想不通啊这个问题困扰了我三年了,希望哪位大侠可以解决它固体的压强很好理解,受的力除以受力面积但是液体和气体的压强实在太抽象了比如说大气压,它的力是怎么 钢瓶防震圈多少钱 手臂静脉输液怎么找血管 关于热力学 气体分子数密度和分子碰撞器壁的次数有什么关系?与压强有什么关系?p=p0×N p0是一个分子造成的压强 N是分子数密度还是碰撞次数 怎么计算,与什么有关?求······谢了 wp=15的二氧化碳气瓶是否需加色环 静脉输液有一种灯可以很明显照射出血管位置,这灯的名字有谁知道 已知:在△ABC中∠A=90°,AD是BC边上的高,BE是角平分线,且交AD于P说明AE=AP的理由 A、B、C、D都是短周期元素,其中B、D处在同一主族,A、B、C三种元素的简单离子都具有与氖原子相同的电子层结构.1molA单质与水反应能置换出1g氢气,B单质与水剧烈反应放出氧气,C最高氧化物既 世界上最大的草原是南美洲的( ) C4H10的密度是多少? 将1g金属置于50ml 5mol/l 的盐酸中,在生成的化合物中,它表现+2价,当酸的浓度降至1mol/l时(设反应前后溶液体积不变),该金属还未反应完,试确定是什么金属? “南美洲的仓库”是什么草原?寒假作业中的题目 已知,在△ABC中,∠A=90°,AD是BC边上的高BE是角平分线,且交AD于P.说明AE=AP的理由 高一化学题目 推断题!原子序数由小到大排列的四种短周期元素X、Y、Z、W,四种元素的原子序数之和为32,在周期表中X是原子半径最小的元素,Y、Z左右相邻,Z、W位于同主族.由X、Y、Z、W四种元素 南美洲的粮仓是哪个草原 高一化学问题:什么是氧化密度? 一条线段把一张长方形的纸分为两部分,四条线段最多能把这张纸分为几部分?十条呢? 在森林中有许多生物,在草原也生物这体现了A 生物种内的多样性B 不同环境下的物种多样性C 生物种内的差异性D 生物种间的差异性 已知,△ABC中,∠A=90°,AD是BC边上的高,BE是∠ABC的角平分线,且交AD于P.求证:AE=AP.没图类对不起了啊 一条线段把一张长方形纸分成两部分,五条线段最多可以分成几部分? 被称为“南美洲的粮仓”的是( )草原~~~~~~~~~~ 已知三角形ABC中,∠A=90°,AD是BC边上的高,BE是角平分线,且交AD于P.求证:AE=AP不要用等腰三角形的性质! 为什么氧气气瓶的剩余压力应不小于0.05兆帕如题 在△ABC中,AB=AC,点P在BC上,若AP=AD,∠DPC=15°,求∠BAP, 求某溶液的密度该怎么求? 各种气体压缩到气瓶内的最高压力是多少比如空气可以压缩到30mpa,但氧气,氮气,二氧化碳等等可以在气瓶中最高压缩到多少就不知道了.说的气体越全越好. 等容变化时为什么压强和热力学温度成正比 如图,△ABC,∩BAC=90°,AD是BC上的高,BE是角平分线,交AD于P,AE=AP若∠C=30°,AE=1,求BC的长 真的存在着十个簸箕与十个斗的传说吗?我是女的,我以后找的老公是不是就得要十个斗的呢?十个簸箕与十个斗的美丽传说 具体的说法到底是什么呢 正物质和反物质之间有万有引力吗 形容朋友之间情谊深厚的成语 物理电动机热功率计算问题有一台电动机,额定电压是220V,正常工作的电流是25A,内部线圈电阻是0.4欧姆.求 改电动机正常工作时的热功率 反物质与正物质之间是斥力还是引力急需解答 形容情谊深的成语 输电线的电阻为R=1Ω,发电机的输出功率为100kw,求下列两种情况下输电线损失的热功率:(1)用10kv的电压输电 (2)用1kv的电压输电 静脉输液时进针后有点血出来是怎么回事?当时针也进了也没肿,滴的也通畅就是输液成功了,可怎么会有点血在我进针的时候出来呢? 赞美音乐才能的成语 表达同学情谊深厚的成语
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘