• 关于android多点触控


    最近项目需要一个多点触控缩放的功能。然后上网查了下资料 总结一下:

    首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion="4"  并且建工程的时候选的是android 2.2就表示你的应用兼容android1.6~android2.2

    之间的版本。但是多点触控的API在1.6~~2,1~~,2,2~~三个版本中都是不一样的。比如android2.2中onTouchEvent(MotionEvent event) 这里可以用event.getActionMasked()

    表示用于多点触控检测点。但在1.6和2.1中并没有event.getActionMasked()这个方法,查源码后发现其实他就是吧event.getAction()& MotionEvent.ACTION_MASK封装了一下。

    对于这些小细节我们要特别注意,因为这关乎版本兼容问题,也许你在2.2的设备上运行没什么问题,但1.6或者2.1就会出个什么问题之类的。所以对于1.6以后新增加的功能,要特别注意API

    的使用。1.5就暂不考虑了。

    接下来看代码:

     1 package laahaa.framework;
    2
    3
    4
    5 import android.content.Context;
    6 import android.graphics.PointF;
    7 import android.util.AttributeSet;
    8 import android.util.FloatMath;
    9 import android.view.MotionEvent;
    10 import android.view.SurfaceHolder;
    11
    12 /**
    13 *
    14 * 游戏画布
    15 */
    16 public class GameView2X extends GameView implements SurfaceHolder.Callback {
    17
    18 private float oldDist;
    19 private PointF midPoint = new PointF();
    20 private boolean isZoom = false;
    21
    22 public GameView2X(Context context, AttributeSet attrs) {
    23 super(context, attrs);
    24
    25 }
    26
    27 public boolean onTouchEvent(MotionEvent event) {
    28
    29 switch (event.getAction() & MotionEvent.ACTION_MASK) {
    30 case MotionEvent.ACTION_DOWN:
    31 super.actionDown(event);
    32 break;
    33 case MotionEvent.ACTION_POINTER_UP:
    34 isZoom = false;
    35 break;
    36 /**
    37 * API原文是 A non-primary pointer has gone down.
    38 * 翻译过来就是:非第一个点按下
    39 */
    40 case MotionEvent.ACTION_POINTER_DOWN:
    41 oldDist = spacing(event);
    42 midPoint(midPoint, event);
    43 isZoom = true;
    44 break;
    45 case MotionEvent.ACTION_MOVE:
    46 if (isZoom) {
    47 float newDist = spacing(event);
    48 /**
    49 * 表示新的距离比两个手指刚触碰的距离大
    50 * ( +10个像素用来延迟一下放大,不然稍微动一点像素,也放大,感觉也太快了。)
    51 */
    52 if (newDist + 10 > oldDist) {
    53 super.getGameThread().getGameDraw()
    54 .checkXY((int) midPoint.x, (int) midPoint.y);
    55 super.getGameThread().getGameDraw().setIsZoom(true);
    56 }
    57 /**
    58 * 表示新的距离比两个手指刚触碰的距离小
    59 */
    60 if (newDist + 10 < oldDist) {
    61 super.getGameThread().getGameDraw().setIsZoom(false);
    62 GameDraw.newX = 0;
    63 GameDraw.newY = 0;
    64 }
    65 }
    66 super.actionMove(event);
    67
    68 break;
    69 }
    70
    71 return true;
    72 }
    73
    74 private float spacing(MotionEvent event) {
    75 float x = event.getX(0) - event.getX(1);
    76 float y = event.getY(0) - event.getY(1);
    77 return FloatMath.sqrt(x * x + y * y);
    78 }
    79
    80 private void midPoint(PointF point, MotionEvent event) {
    81 float x = event.getX(0) + event.getX(1);
    82 float y = event.getY(0) + event.getY(1);
    83 point.set(x / 2, y / 2);
    84 }
    85 }


    这里要注意下GameView2X表示2.0以上的版本 他继承于我自己写的低版本的GameView。因为有很多重复代码继承是必须的。最后要注意下:获取当前应用的SDK版本代码为:

    int sdkVersion=Integer.parseInt(Build.VERSION.SDK);

    你需要在最开始初始化的时候运行它,写入GameConfig中比较好,后面单例调用就好了。或者不喜欢单例的直接static final 也行。然后再选择gameview的时候 加个if判断,

    if(sdkVersion<Build.VERSION_CODES.ECLAIR)

    {}

    else

    {}

    好了,这里的多点触控放大比较简单,其实可以根据前距离/后距离的比值来动态设置缩放。这只是个简单的例子。

    ps:最近发现 onTouchEvent事件中的参数MotionEvent,它有一个getSize()方法。在一个点的时候,该方法永远返回0,而在两个触电的时候,该方法则根据两点相对位置变化而返回不同的值 

  • 相关阅读:
    PathInfo模式,thinkPHP模板与控制之间的关系
    thinkPHP无法显示验证码问题
    jQuery.validate 中文API手册
    MySQL 常用函数
    MySQL插入、更新与删除数据 习题
    MySQL查询语句练习题
    在windows下SphinxCoreseek的配置安装与测试
    Ubuntu上Coreseek+PHP的安装
    Ubuntu下安装CoreSeek
    Ubuntu更新命令
  • 原文地址:https://www.cnblogs.com/tianjian/p/2270657.html
Copyright © 2020-2023  润新知