本文原创,转载请注明:http://blog.csdn.net/cloudzfy1/article/details/6582707

Google 暑期大学生博客分享大赛 - 2011 Android 成长篇

如果您喜欢本文,请您投一下票: http://www.google.com/intl/zh-CN/daxue/blog/vote.html#tab2
谢谢。

最近需要做个Android的项目,需要使用多点触控的功能,上网找了很久,中文方面的资料相当少,英文方面也不多,经过自己的研究,加上对已知的一些资料的整理,下面为大家介绍一下Android多点触控程序的编写。

首先,我们准备好一张图片:

在Eclipse下新建一个Android工程(和一般Android工程一样),需要注意的是:Android的多点触控功能需要运行在Android 2.0版本以上。

完成后,我们需要将原先准备好的图片放进res/drawable文件夹下(注意,如果是Android2.2,请放在三个drawable文件夹下),如图所示:

该图片是为了给该多点触控的实例提供运行环境,实现图片的放大和缩小。

下面,我们来修改一下main.xml文件,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent">
<ImageView android:id="@+id/imageView"android:layout_width="fill_parent"android:layout_height="fill_parent"android:src="@drawable/img"android:scaleType="matrix" >
</ImageView>
</LinearLayout>

对于让一张静态图片在Android面板上显示,我们可以采用下面的一句话:

ImageView imageView = (ImageView)findViewById(R.id.imageView);

通过设置Matrix,我们可以获得对ImageView的一些基本操作。

OK,啰嗦这么多,下面进入主题:

我们需要实现一个OnTouchListener的方法,来设置ImageView的侦听属性,该接口位于android.view.View.OnTouchListener。

实现onTouch(View view, MotionEvent event)的方法,就可以获取触屏的感应事件了。

在该事件中,有两个参数可以用来获取对触摸的控制,这两个参数分别为:MotionEvent.getAction()和MotionEvent.ACTION_MASK,前者用于对单点触控进行操作,后者用于对多点触控进行操作,相应地,我们可以通过Android Developers’ Reference看到,对于单点触控,我们由MotionEvent.getAction()可以得到以下几种事件:ACTION_DOWN、ACTION_UP,而对于多点触控,由MotionEvent.ACTION_MASK,我们可以得到:ACTION_POINTER_DOWN、ACTION_POINTER_UP,都是MotionEvent中的常量,可以直接调用。而有些常量则是单点和多点共用的,如:ACTION_MOVE,因此在按下时,我们必须标记单点与多点触控的区别。

下面我们来介绍一下缩放功能的实现,对于缩放,我们定义有两种手势,一种是双指拉伸式,一种是单指旋转式。

首先,双指拉伸式。

这是一种比较常规的图片缩放方式,实现起来也比较方便,我们可以很容易想到,在处理多点触控事件时,如果没有别的手势干扰,我们只需检测两指按下时和移动之后的位置关系即可,如果距离变大,则是放大图片;反之则是缩小图片。

主要代码如下:

if(mode == ZOOM)
{float newDistance;newDistance = (float)Math.sqrt((event.getX(0)-event.getX(1))*(event.getX(0)-event.getX(1))+(event.getY(0)-event.getY(1))*(event.getY(0)-event.getY(1)));if(newDistance > 10f) {matrix.set(savedMatrix);matrix.postScale(newDistance/oldDistance, newDistance/oldDistance, mid.x, mid.y);oldDistance = newDistance;savedMatrix.set(matrix);}
}

然后,单指旋转式。

这是一种单指操作中比较流行的方式,然而实现起来并非特别方便。具体说来,我们可以定义顺时针转动为图片放大,逆时针转动为图片缩小。在没有其他干扰项的时候,我们可以通过捕获三次连续移动来得知手势顺时针还是逆时针。如下图所示,我们把前两次的位置作一个向量A,后两次位置作一个向量B,如果向量B比向量A大,则是逆时针;向量B比向量A小则是顺时针。当然,我们这里就要用到反三角函数,同时要注意2pi的角度问题哦~

注意:在处理同为单指操作或者同为多指操作的时候,要考虑不同行为之间的区别。

主要代码如下:

if (mode == MOVE)
{if(rotate == NONE) {savedMatrix.set(matrix);mid.set(event.getX(), event.getY());rotate = ROTATION;}else {matrix.set(savedMatrix);double a = Math.atan((mid.y-start.y)/(mid.x-start.x));double b = Math.atan((event.getY()-mid.y)/(event.getX()-mid.x));if ((b - a < Math.PI/2 && b - a > Math.PI / 18)||((b + Math.PI) % Math.PI - a < Math.PI/2 && (b + Math.PI) % Math.PI - a > Math.PI / 18)) {matrix.postScale((float)0.9, (float)0.9);}else if ((a - b < Math.PI / 2 && a - b > Math.PI / 18)||((a + Math.PI) % Math.PI - b < Math.PI/2 && (a + Math.PI) % Math.PI - b > Math.PI / 18)) {matrix.postScale((float)1.1, (float)1.1);}start.set(event.getX(), event.getY());rotate = NONE;}
}

下面是实现的结果截图:

初始画面:

通过鼠标顺时针转动后的效果图:

通过鼠标逆时针转动后的效果图:

下面是代码的具体解析:

TouchActivity.java

package example.MultiTouch;import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;public class TouchActivity extends Activity {private static final int NONE = 0;private static final int MOVE = 1;private static final int ZOOM = 2;private static final int ROTATION = 1;private int mode = NONE;private Matrix matrix = new Matrix();private Matrix savedMatrix = new Matrix();private PointF start = new PointF();private PointF mid = new PointF();private float s = 0;private float oldDistance;private int rotate = NONE;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);ImageView imageView = (ImageView)findViewById(R.id.imageView);imageView.setOnTouchListener(new OnTouchListener(){@Overridepublic boolean onTouch(View view, MotionEvent event) {ImageView imageView = (ImageView)view;switch (event.getAction()&MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:savedMatrix.set(matrix);start.set(event.getX(), event.getY());mode = MOVE;rotate = NONE;break;case MotionEvent.ACTION_UP:case MotionEvent.ACTION_POINTER_UP:mode = NONE;break;case MotionEvent.ACTION_POINTER_DOWN:oldDistance = (float)Math.sqrt((event.getX(0)-event.getX(1))*(event.getX(0)-event.getX(1))+(event.getY(0)-event.getY(1))*(event.getY(0)-event.getY(1)));if (oldDistance > 10f) {savedMatrix.set(matrix);mid.set((event.getX(0)+event.getX(1))/2, (event.getY(0)+event.getY(1))/2);mode = ZOOM;}case MotionEvent.ACTION_MOVE:if (mode == MOVE){if(rotate == NONE) {savedMatrix.set(matrix);mid.set(event.getX(), event.getY());rotate = ROTATION;}else {matrix.set(savedMatrix);double a = Math.atan((mid.y-start.y)/(mid.x-start.x));double b = Math.atan((event.getY()-mid.y)/(event.getX()-mid.x));if ((b - a < Math.PI/2 && b - a > Math.PI / 18)||((b + Math.PI) % Math.PI - a < Math.PI/2 && (b + Math.PI) % Math.PI - a > Math.PI / 18)) {matrix.postScale((float)0.9, (float)0.9);}else if ((a - b < Math.PI / 2 && a - b > Math.PI / 18)||((a + Math.PI) % Math.PI - b < Math.PI/2 && (a + Math.PI) % Math.PI - b > Math.PI / 18)) {matrix.postScale((float)1.1, (float)1.1);}start.set(event.getX(), event.getY());rotate = NONE;}}else if(mode == ZOOM){float newDistance;newDistance = (float)Math.sqrt((event.getX(0)-event.getX(1))*(event.getX(0)-event.getX(1))+(event.getY(0)-event.getY(1))*(event.getY(0)-event.getY(1)));if(newDistance > 10f) {matrix.set(savedMatrix);matrix.postScale(newDistance/oldDistance, newDistance/oldDistance, mid.x, mid.y);oldDistance = newDistance;savedMatrix.set(matrix);}}break;}imageView.setImageMatrix(matrix);return true;}});}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="example.MultiTouch"android:versionCode="1"android:versionName="1.0"><uses-sdk android:minSdkVersion="8" /><application android:icon="@drawable/icon" android:label="@string/app_name"><activity android:name=".TouchActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

Android多点触控揭秘相关推荐

  1. Android多点触控详解

    本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...

  2. 模拟Android多点触控

    Android多点触控 Android多点触控 多点触控实现思路 第一种adb shell input方式 第二种adb shell sendevent方式 多点触控实现思路   经过资料的查询,要在 ...

  3. Android多点触控技术

    1 简介 Android多点触控在本质上需要LCD驱动和程序本身设计上支持,目前市面上HTC.Motorola和Samsung等知名厂商只要使用电容屏触控原理的手机均可以支持多点触控Multitouc ...

  4. Android 多点触控消息捕获与处理

    1 简介 Android多点触控在本质上需要LCD驱动和程序本身设计上支持,目前市面上HTC.Motorola和Samsung等知名厂商只要使用电容屏触控原理的手机均可以支持多点触控Multitouc ...

  5. Android 多点触控 MotionEvent详解

    相关API 介绍 MotionEvent.getY() 和 MotionEvent.getRawY() 的区别 getY 表示触摸事件在当前的View内的Y 坐标, getRawY表示触摸事件在整个屏 ...

  6. Android多点触控MultiTouch浅析

    申明: 参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0226/914.html 下面实现如何通过应用层支持多点触控操作, ...

  7. android 多点触控缩放,Android多点触控(图片的缩放Demo)

    本文主要介绍Android的多点触控,使用了一个图片缩放的实例,来更好的说明其原理.需要实现OnTouchListener接口,重写其中的onTouch方法. 实现效果图: 源代码: 布局文件: ac ...

  8. 关于android多点触控

    最近项目需要一个多点触控缩放的功能.然后上网查了下资料 总结一下: 首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion ...

  9. android多点触控

    网上搜索后有很多的多点触控的东西,自己也写个吧,实现的就是在屏幕上画个圆角的矩形随着2点的大小而变换. 下面的东西是在网上找的一个例子然后自己更改的. View Code 1 package com. ...

最新文章

  1. 对比 MySQL 的 Binlog 日志处理工具
  2. 51CTO手機軟件有病毒? 有網絡安全的高手嗎?
  3. 重写(override / overwrite)
  4. oracle中xml如何存储过程,oracle存储过程生成xml文件
  5. oracle中入库判断空串,不同数据库和SpringDataJPA对字段值null,''空值的判断
  6. Zeppelie连接jdbc的使用
  7. 如何无信用卡申请谷歌云
  8. android进入recovery模式,Android关机重启至recovery安卓进入Recovery模式模式
  9. 如何搭建内测托管平台?有可以直接用的内测托管平台吗?
  10. Ubuntu18.04出现无WIFI适配器解决方法汇总
  11. C语言代码老师,王耀辉老师给出的178个经典c语
  12. 云重磅 | 阿里巴巴平均每天纳税超1.4亿;谷歌、Face book与AWS将共建美欧新海底电缆;阿里发布谣言粉碎机:1秒辨真伪...
  13. 手把手教你玩转android应用Microsoft Remote Desktop
  14. ARM LDR汇编指令
  15. 管理模型 - RACI模型
  16. WHQL认证资讯:关于Windows硬件开发者仪表盘
  17. MySQL 联合索引(复合索引)详解
  18. Typescript 面向对象
  19. matlab吃cpu还是显卡_在GPU上运行MATLAB程序
  20. 基于python的word批量图文排版

热门文章

  1. C语言学习教程:搬山游戏开发源码
  2. Beyond Cmpare下载安装教程
  3. 基于外卖平台POI的城市餐饮业空间热点分析系统
  4. 查看虚拟机vmware下linux的ip
  5. python123m与n的数学运算_【Python数学面试题】面试问题:Python“… - 看准网
  6. 代扣代收 VS 代付代发
  7. 【基于MapReduce的成绩分析系统】——计算每门课程的平均成绩、最高成绩、最低成绩
  8. PL0功能扩充(浮点数,数组,数组加减乘除等)
  9. LZY的计算器(暴力)
  10. vue中怎么把图片转换成base64字符串 , 以及base64字符串怎么转换成图片路径