Android中的多点触摸

news/2024/11/17 22:33:11/

我的学习视频地址,一起来学习Android…
http://edu.csdn.net/course/detail/2741/43164?auto_start=1>
代码下载地址

代码一:自定义支持多点触摸的TextView
http://download.csdn.net/detail/zhiyuan0932/9513852

什么是多点触摸

允许计算机用户同时通过多个手指来控制图形界面的一种技术

多点触摸的应用场景

  • 对图片、文字、网页进行放大或者缩小
  • 多手指手势操作自定义控件和布局

触摸事件的重要方法

  • event.getActionMasked(); 获取事件类型
    在只使用单手指操作的时候,这个方法我们一般使用的是event.getAction(),来获取事件类型,但是对于多个手指,我们使用event.getActionMasked()或者event.getAction() & MotionEvent.ACTION_MASK 来获取支持多个手指触摸的事件类型。

  • MotionEvent.ACTION_POINTER_DOWN 手指按下事件
    这个方法可以获取到多个手指按下的状态

  • MotionEvent.ACTION_POINTER_UP 手指抬起事件
    这个方法可以获取到多个手指抬起的状态

  • MotionEvent.ACTION_MOVE 手指移动事件

  • event.getPointerCount() 获取手指个数
    这个方法是获取当前手指的个数

案例一:通过两指触摸实现字体缩放

  • 在这里直接贴代码,首先贴出布局代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><com.example.scaletextview.ZoomTextViewandroid:id="@+id/textView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_centerInParent="true"android:gravity="center"android:text="@string/hello_world"android:textSize="30sp" /></RelativeLayout>
  • 贴出自定义支持多点触控的TextView代码
package com.example.scaletextview;import android.content.Context;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;public class ZoomTextView extends TextView {private static final String TAG = "ZoomTextView";private float textSize;private int mode;private float oldDist;public ZoomTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public ZoomTextView(Context context, AttributeSet attrs) {super(context, attrs);}public ZoomTextView(Context context) {super(context);}/*** 处理TextView的触摸事件*/@Overridepublic boolean onTouchEvent(MotionEvent event) {//在一开始,计算当前字体的大小if (textSize == 0) {textSize = this.getTextSize();}// 获取触摸事件的类型,如果是单点是event.getAction(),当涉及到多点触控时,就使用getActionMasked来获取触摸事件类型switch (event.getActionMasked()) {case MotionEvent.ACTION_POINTER_DOWN:// 当手指按下的时候,就去获取当前手指的间距oldDist = spacing(event);break;case MotionEvent.ACTION_MOVE:// 获取当前触摸点的个数if (event.getPointerCount() >= 2) {// 如果触摸点>=2 获取当前两个手指的距离,然后进行缩放float newDist = spacing(event);zoom(newDist / oldDist);//重新置位oldDist = newDist;}break;}return true;}/*** 不断进行缩放* * @param f*/private void zoom(float f) {textSize *= f;this.setTextSize(px2sp(getContext(), textSize));}/*** 将px值转换为sp值,保证文字大小不变* * @param pxValue* @param fontScale*            (DisplayMetrics类中属性scaledDensity)* @return*/public static int px2sp(Context context, float pxValue) {float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (pxValue / fontScale + 0.5f);}/*** 计算两个手指的大小* * @param event* @return*/private float spacing(MotionEvent event) {//获取第一个点的x坐标和第二个点的x坐标float x = event.getX(0) - event.getX(1);//分别获取y坐标float y = event.getY(0) - event.getY(1);//使用勾股定理计算两点距离return FloatMath.sqrt(x * x + y * y);}
}

案例二:通过两指触摸实现图片缩放

  • 第一步:写一个自定义控件继承自View,并计算控件宽高
        public class ScaleImageView extends View//在onMeasure方法中计算出当前控件的宽和高@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);width = this.getWidth();height = this.getHeight();}
  • 第二步:对外提供设置图片的方法
public void setImageResource(int resourceId) {Bitmap mbitmap = BitmapFactory.decodeResource(getResources(),resourceId);this.mBitmap = mbitmap;postInvalidate();}// 对外提供设置图片的方法public void setImageBitmap(Bitmap mBitmap) {this.mBitmap = mBitmap;// 当传递过图片来之后,对图片进行初始化操作postInvalidate();}
  • 第三步:对图片进行初始化的处理(图片过大需要进行等比例缩放处理),然后将图片绘制到界面上
    //进行图片的初始化public void initBitmap(Canvas canvas) {if (mBitmap != null) {matrix.reset();int bitmapWidth = mBitmap.getWidth();int bitmapHeight = mBitmap.getHeight();if (bitmapWidth > width || bitmapHeight > height) {if (bitmapWidth - width > bitmapHeight - height) {// 当图片宽度大于屏幕宽度时,将图片等比例压缩,使它可以完全显示出来float ratio = width / (bitmapWidth * 1.0f);matrix.postScale(ratio, ratio);float translateY = (height - (bitmapHeight * ratio)) / 2f;// 在纵坐标方向上进行偏移,以保证图片居中显示matrix.postTranslate(0, translateY);totalTranslateY = translateY;totalScaleRadio = initScaleRadio = ratio;} else {// 当图片高度大于屏幕高度时,将图片等比例压缩,使它可以完全显示出来float ratio = height / (bitmapHeight * 1.0f);matrix.postScale(ratio, ratio);float translateX = (width - (bitmapWidth * ratio)) / 2f;// 在横坐标方向上进行偏移,以保证图片居中显示matrix.postTranslate(translateX, 0);totalTranslateX = translateX;totalScaleRadio = initScaleRadio = ratio;}currentBitmapWidth = bitmapWidth * initScaleRadio;currentBitmapHeight = bitmapHeight * initScaleRadio;} else {// 当图片的宽高都小于屏幕宽高时,直接让图片居中显示float translateX = (width - mBitmap.getWidth()) / 2f;float translateY = (height - mBitmap.getHeight()) / 2f;matrix.postTranslate(translateX, translateY);totalTranslateX = translateX;totalTranslateY = translateY;totalScaleRadio = initScaleRadio = 1f;currentBitmapWidth = bitmapWidth;currentBitmapHeight = bitmapHeight;}canvas.drawBitmap(mBitmap, matrix, null);}}

在进行初始化处理的时候,需要对图片进行缩放和移动,这里将图片小于控件时的偏移量计算原理贴出,方便大家理解这里写图片描述
* 第四步:处理onTouch事件
*

/*** 处理触摸事件*/@Overridepublic boolean onTouchEvent(MotionEvent event) {// 获取触摸事件的类型,如果是单点是event.getAction(),当涉及到多点触控时,就使用getActionMasked来获取触摸事件类型switch (event.getActionMasked()) {case MotionEvent.ACTION_POINTER_DOWN:if (event.getPointerCount() >= 2) {// 计算两个手指的距离oldDist = spacing(event);}break;case MotionEvent.ACTION_MOVE:// 获取当前触摸点的个数if (event.getPointerCount() >= 2) {centerPoniter(event);// 如果触摸点>=2 获取当前两个手指的距离,然后进行缩放// 重新置位float newDist = spacing(event);// 进行缩放currentState = STATE_ZOOM;// 计算出当前的缩放值scaleRatio = newDist / oldDist;// 调用onDraw方法,重新绘制界面postInvalidate();// 对手指间距离进行重新置位oldDist = newDist;}break;}return true;}
  • 第五步 进行图片的缩放处理
    private void zoom(Canvas canvas) {totalScaleRadio = totalScaleRadio * scaleRatio;//这里是对图片的放大和缩小进行一定的限制//最大不超过图片的4倍,最小不小于源图片的大小if (totalScaleRadio >= initScaleRadio * 4) {totalScaleRadio = initScaleRadio * 4;} else if (totalScaleRadio < initScaleRadio) {totalScaleRadio = initScaleRadio;}matrix.reset();// 将图片按总缩放比例进行缩放matrix.postScale(totalScaleRadio, totalScaleRadio);float scaledWidth = mBitmap.getWidth() * totalScaleRadio;float scaledHeight = mBitmap.getHeight() * totalScaleRadio;float translateX = 0f;float translateY = 0f;// 如果当前图片宽度小于屏幕宽度,则按屏幕中心的横坐标进行水平缩放。否则按两指的中心点的横坐标进行水平缩放if (currentBitmapWidth < width) {translateX = (width - currentBitmapWidth) / 2f;} else {//当图片大于控件的大小时,需要去计算出这个偏移量的大小,随后附加图片对这个计算原理做介绍translateX = mTranslateX * scaleRatio + fingerCenterX* (1 - scaleRatio);// 进行边界检查,保证图片缩放后在水平方向上不会偏移出屏幕// 当当前图片比屏幕大的时候,要保证不再往右偏,否则就会在右侧移除屏幕if (translateX > 0) {translateX = 0;// 保证当图片比屏幕大的时候,屏幕宽--左偏的一个大小,不得大于图片的实际大小} else if (width - translateX > scaledWidth) {translateX = width - scaledWidth;}}// 如果当前图片高度小于屏幕高度,则按屏幕中心的纵坐标进行垂直缩放。否则按两指的中心点的纵坐标进行垂直缩放if (currentBitmapHeight < height) {translateY = (height - currentBitmapHeight) / 2f;} else {//跟x轴上的偏移量是一个道理translateY = mTranslateY * scaleRatio + fingerCenterY* (1 - scaleRatio);// 进行边界检查,保证图片缩放后在垂直方向上不会偏移出屏幕if (translateY > 0) {translateY = 0;} else if (height - translateY > scaledHeight) {translateY = height - scaledHeight;}}// 缩放后对图片进行偏移,以保证缩放后中心点位置不变matrix.postTranslate(translateX, translateY);mTranslateX = translateX;mTranslateY = translateY;currentBitmapWidth = scaledWidth;currentBitmapHeight = scaledHeight;canvas.drawBitmap(mBitmap, matrix, null);}

下面贴出当图片 大于控件大小时,手指进行缩放时的X轴的偏移量计算原理,来方便大家的理解
这里写图片描述

计算手指距离和手指中心的方法

/*** 计算两个手指间的距离* @param event* @return*/private float spacing(MotionEvent event) {// 获取第一个点的x坐标和第二个点的x坐标float x = event.getX(0) - event.getX(1);// 分别获取y坐标float y = event.getY(0) - event.getY(1);// 使用勾股定理计算两点距离return FloatMath.sqrt(x * x + y * y);}/*** 计算手指的中心点* @param event*/private void centerPoniter(MotionEvent event) {float x0 = event.getX(0);float x1 = event.getX(1);float y0 = event.getY(0);float y1 = event.getY(1);fingerCenterX = (x0 + x1) / 2;fingerCenterY = (y0 + y1) / 2;}

http://www.ppmy.cn/news/484977.html

相关文章

STM32模拟USB多点触控屏

STM32模拟USB多点触控屏 开发准备 STM32的USB官方例程库JoyStickMouseSTM32F103RCWindows7 代码修改 1.usb_pwr.c RESULT PowerOn(void) {u16 wRegVal; //USB_Cable_Config(ENABLE);//这里由于硬件问题用不到&#xff0c;注释/*** CNTR_PWDN 0 ***/w…

多点触控参数

简介 为了使用功能强大的多点触控设备&#xff0c;就需要一种方案去上报用户层所需的详细的手指触摸数据。这个文档所描述的多点触控协议可以让内核驱动程序向用户层上报任意多指的数据信息。 使用说明 单点触摸信息是以ABS承载并按一定顺序发送&#xff0c;如BTN_TOUCH、ABS…

C语言易错剖析(1)-数据类型

C语言易错剖析 int8_t、int16_t、int32_t、int64_t、uint8_t、size_t、ssize_t等数据类型 int_t同类 int_t 为一个结构的标注&#xff0c;可以理解为type/typedef的缩写&#xff0c;表示它是通过typedef定义的&#xff0c;而不是一种新的数据类型。因为跨平台&#xff0c;不…

多点触控与单点触控

private ImageView mImageView;private Matrix matrix new Matrix();private Matrix savedMatrix new Matrix();private static final int NONE 0;private static final int DRAG 1;private static final int ZOOM 2;private int mode NONE;// 第一个按下的手指的点priv…

多点触摸处理

接着上文&#xff0c;我们做了一个简陋的下拉刷新控件&#xff0c;目前用到的知识点有 view的滑动view的弹性滑动事件分发机制事件分发机制的两个小问题&#xff08;事件的二次分发&#xff09; 目前这个控件除了简陋一点&#xff0c;没做抽象封装&#xff0c;在单手操作下&a…

多点触控 - MFC

概述 Windows 7 支持用户通过手指接触来管理应用程序&#xff0c;无需使用中间设备。这扩展了平板 PC 基于触笔的功能。与其他指针设备不同&#xff0c;这种新功能允许多个输入事件在不同指针位置同时发生&#xff0c;它还支持复杂的场景&#xff0c;比如通过十个手指或多个并…

多点触控

1.要了解多点触控&#xff0c;我们必须先了解一下View的生命周期&#xff0c;毕竟在Android用的到多点触控的地方&#xff0c;一般都是自定义控件。就像Fragment和Activity都有生命周期一样&#xff0c;View也有自己的生命周期。该生命周期并不直接和展示它的Fragment或者Activ…

多点触摸屏技术

多点触摸屏技术 2006年02月苹果申请了一些多点触摸屏的专利(multipoint)&#xff0c;今天苹果公司提供了完整的iPod产品线&#xff0c;并且引入了带有触摸屏和多点触摸技术的iPod。参见&#xff1a;苹果将发布更便宜更创带无线的新iPod 一年前还感叹QQ的概念QQ版&#xff0c;…