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

手势识别兼容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开发网将在以后的时间中介绍。

2013中国智能交通与大数据技术峰会:迎接交通大数据新时代 大数据应用技术(上):加速创新,重塑世界 英特尔百度携手推出首个跨平台应用商店 12月9日:计算机软件第一夫人Grace Hopper出生 触摸屏将成笔记本标配 电脑行业或将迎来又一春 触摸4G,你必须要知道的那些事儿 TIOBE 2013年12月编程语言排行榜:Transact-SQL冲刺年度语言 敏捷开发的6个实战经验 【图文】走近华为企业业务与支撑万人技术团队的云数据中心 《习惯联盟》陈晓冬:与京东云合作让我们没有后顾之忧 流计算与批处理同现:畅享大数据时代的开源实践 挑战和机遇并存:大数据时代机器学习与可视化 【企业开源系列】收发一条Twitter推文的背后 在IE11中更快地获得您需要的内容 暴露程序员身份的8个行为 英特尔创新应用大赛大评审!创新也有中国风 苹果面临一问题:正源源不断地失去优秀工程师 初学编程者必知的五个网站 大数据基准测试专题论坛:基准测试是一把尚未完成的尺子 大数据应用(下):应用驱动技术,DaaS创造价值 大数据研究与发展专题论坛:大数据在各领域中的应用及发展策略 雅虎新目标:欲收购照片分享网站Imgur 移动开发工具访谈《近匠》第01期:七牛云存储—BaaS进化论 ShareSDK:A轮融资到位!将推社会化评论SDK 70美元,你也能用Raspberry Pi做个专属iBeacon基站 7个鲜为人知却超实用的PHP函数 从管理远程式团队和分布式团队中所获得的宝贵经验 Netflix开源数据流管理器Suro Google新创意:天花板加麦克风 人脑植芯片 苹果获弯曲屏新专利 可给手机弄个大波浪卷 真正的跨平台硬件测试:3DMark已打通PC、iOS、Android 请教用PHP开发物业收费软件的开行性! 谁有C++经典书籍电子版 VC技术内幕的电子版pdg文件格式要用何种工具才能浏览??? 请教各位:一个运行notes c++ api 的超级菜问题: 推荐一下制作GIF的免费软件. 关于双系统!!! 如何将数据库中保存的word文件读出并在IE中大开? 关于acmStreamOpen的问题? 关于editmask的问题 TURBOC 3.0的问题,在线等待..... 各位高手!我又一问题请教!请帮忙!!! IIS如何与Tomcat结合,请指教! 如何用java访问Excel文件? 如何添加空记录 非常着急!!请高手赐教!我刚注册,只有200分奉送!!谢谢!!! 哪儿可以提供ExpressNavBar vcl下? 各位高手快来指点一下,是关于动态创建组件的! 自己定义CMP的finder定位器的问题 四舍五入问题 请教牛人,能不能发一段java中有关计时的程序 一个小问题,请大侠指点,立即给分!!! 关于三角函数的问题 一个三百年前已忘得一干二净的问题 打包!!!问题问题。。。在线..... 一个c的问题!! [100分求救]在Canvas或Applet上画的图应该怎样输出为jpg图象呢? 用VC的console application 到底能编多大的程序? 关于程序在初始化时候注册窗口类的问题? 上网很慢 请问从log文件里都能得到哪些信息? 系统设计一般把数据表放一个数据库中还是分到多个数据库中? 树型控件的问题,PB8.03版本,大家遇到过吗? 强烈支持雍亲王倒分!!(江湖无赖) 怎样调用VC写的DLL 同步 兄弟们,我的rh8中怎么没有中文输入法? 在access中如何用函数?我怎么找不到函数库啊。那里有关于access的函数库教程? 请教 我装的DELPHI7.0不知为何在区域设置为“英文”是看到的汉字都成了“????”? <iframe>如何改变大小? 关于水晶报表的问题!(急!!!!)(在线等待~~~~~~~~) 关于vb脚本中运用三角函数的问题 一个三百年前已忘得一干二净的问题 cbc+数据库的问题????????? 能不能控制<input type='fele' ...>的文件类型,如不可输入(readonly全部都不能用了) 在线等待:谁有个最简单的加密算法? 谁有More Effective中文电子书! 请教一段java计时器的问题(送分了) 在ASP中能不能引用.net的框架组件,能的话该怎么做? 占便宜歌 不想周末加班了,帮我啊兄弟们! 小弟是2003年毕业生,想找个软件工程师工作,不知道有什么要求? 一个简单的添加记录语句,求解! 求一篇武则天的无字碑的1000字左右作文不胜感激~~~~~~~~~ 你读了自己的花是让别人看这篇文章的读后感.300字大部分要说人人为我,我为人人 已知2-根号7的整数部分是a,小数部分是b,试求b(ab+6)的值 有关月亮的比喻句必须是自己造的 could you please buy _____drinks and snacks?could you please buy _____drinks and snacks?sorry .I do not have _____money .A.some ,any B.any ,any C.any ,some any可用于疑问,为什么不能选, “殄”这个字怎么读? bec高级水平是什么水平啊 could you please buy( )snacks( )drinks?填 some and还是any or 上面是号字下面是食字 ,上面是一个殄字下面是一个食字.这两个字怎么念是什么意思 武则天简史(200字内) 根据首字母完成单词:-Could you please buy some drinks and snacks?-No,I____(不同意) 他这么说是啥含义阿 武则天的评价(200字左右)简单评价了武则天的功过 7. Who is the girl _____ wearing a red dress?A. whose B. that C. whom D. that’s7. Who is the girl _____ wearing a red dress?  A. whose   B. that   C. whom   D. that’s为什么这道题选D? "殄"这个字读什么? 武则天50字介绍 英语组词成句:girl,young,who,red,is,in,that,(.) 男的一般这么说是什么意思啊.女的 22:35:33 有事么. 男的 22:37:44 没事,跟你聊会儿天 女的 22:39:02 你是坐那谁旁边那个男孩子. 男的 22:41:44 哎!聪明!呵呵 女的 22:42:15 呵呵. 男的 22:43:57 今我们 为武则天写碑文 200字 十万火急! 什么水平才能考BEC高级?我的英语六级只考了500分,听力比较弱这个水平可以考BEC高级吗?还是考BEC中级比较好?考中级对找工作有用吗? 殄文怎么读 月亮的比喻句要新鲜的,不要晓夜,残月如死神之镰,将白惨惨的光洒在破败的墓地上月亮像一把冰冷的尖刀,插入游子的心.弯弯的月儿小小的船,小小的船儿两头尖.月亮象小船,弯弯的两头尖; 月 一个英语句子的困惑similarly,a king's servant might not be the best one to write a biography of that king,but a foreigner might not have the knowledge and sympathy necessary to write the king's biography-not for a readership from within the k 一个美女主动和我视频 然后我 问她我丑不丑 她说 这都不是事.是事就一阵.一阵就一会儿.一会儿就完事 BEC 高级 听力哪位有BEC高级 第四辑 听力的材料MP3什么的,能不能发给我, 萎靡的读音萎靡 的读音 关于暴殄天物的殄是殄,不是殓 第二大题怎么写 BEC高级听力多少分大概能拿A 已知3+根号7/2的整数部分是a,小数部分是b,求500a^2+(1+根号7)ab+4的值 怎么写第二大题 求BEC高级听力(2-4辑)! 《春夜喜雨》中的“花重锦官城”中的‘重’字的读音. 第二大题,怎么写 bec高级听力不过还有希望过吗我考了2010年的高级bec,但是听力指定过不了,还有希望过吗,有没有考过高级的亲身经历听力没过但高级过了的同学啊. “一帆风顺”中“帆”的读音到底是第一声还是第二声?“帆”的拼音只有一个第一声的,为什么在“一帆风顺”中“帆”字大多数人都是第二声? 关于月亮的比喻句5.6句就好,但要生动,要长(也不要太长了,长一点就好) 河南省高一化学必修一拔高题多多益善,若是超过5题得就给5分,10题10分.答案也要 风靡全球发音?是不是第三声?靡 读第二声是不是只是 奢靡,其他全部第三声 关于月亮的比喻句耐心回答一下吧! 第二大题怎么写, 已知根号10的整数部分是a,小数部分是b,求a²+b²(谢谢, 喷洒氧化乐果农药与怀孕 医生请进.我在喷洒氧化乐果农药后一个月内.(未采取任何安全措施)我爱人怀孕了.奔三的人了.盼望孩子已久.现在孩子已经快两个月了.真是非常的担心.望高人指 第二大题怎么写求解啊! who is the girl ( ) red 氧化乐果农药放置时间长了会失效么?我是说超过保质期以后.有研究的可以给我留言,.我是学化学的,. 求解第二大题.短文填空 who is the girl a red hat? 八年级物理问题(关于电热的)为什么串联电路中导体放出的热量与电阻成正比,而并联电路中导体放出的热量却与电阻成反比?不要用物理公式来解释,用原理来解释!(我想到脑都爆了还没想 ----Could you please help me carry the box?Its too heavy.----( )A.Sorry.I have no time.S.Its my p为什么不选A呢 who is the girl ( )red there?A./ B.over C.with D.in 物理w=qu怎样记牢? 月亮升上来了比喻句 Could you help me buy some____(many)drinks and snacks. 我眼中的武则天1000字求求你们了!发发慈悲吧!再不告我就死翘了!谢谢了 BEC中级和6级哪个难 could you buy some drinks为什么用some,不是用any吗 一篇关于武则天的论文1000字 种出来的花上面有字看到在蛋里浇水能种出有字的花.不知道怎么种的.有谁在种给我联系好吗?先,提供可靠情报者,追加500分再说, 一个让人很困惑的英语句子---务必高手进As the bus began coming near the school I wondered what my teacher would be like .我还看在网上看到过这样的句子:As the bus began coming near to the school I wondered what my teacher
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘