文章目录

  • 一、安卓触摸事件概述
    • 1、触摸分类
      • (1)单点触摸
      • (2)多点触摸
    • 2、触摸动作
    • 3、触摸监听器
    • 4、触摸方法
    • 5、触点个数与坐标
    • 6、安卓触摸事件处理机制
  • 二、案例演示:通过单点触摸移动米老鼠
    • 1、创建安卓应用
    • 2、准备图片素材
    • 3、字符串资源文件
    • 4、主布局资源文件
    • 5、主界面类实现功能
    • 6、优化主界面类
    • 7、效果
  • 三、案例演示:通过多点触摸缩放米老鼠
    • 1、创建安卓应用
    • 2、准备图片素材
    • 3、字符串资源文件
    • 4、主布局资源文件
    • 5、主界面类实现功能

一、安卓触摸事件概述

1、触摸分类

(1)单点触摸

  • 单点触控,只能识别和支持每次一个手指的触控、点击,若同时有两个以上的点被触碰,就不能做出正确反应。很多医院、图书馆等的大厅都有这种触控技术的电脑,支持触摸屏的手机、MP3、数码相机也多采用这种单点触控技术。

(2)多点触摸

  • 多点触控(又称多重触控、多点感应、多重感应,英文MultitouchMulti-Touch)是采用人机交互技术与硬件设备共同实现的技术,能在没有传统输入设备(如鼠标、键盘等)。下进行计算机的人机交互操作。多点触摸技术,能构成一个触摸屏(屏幕,桌面,墙壁等)或触控板,都能够同时接受来自屏幕上多个点进行计算机的人机交互操作。

2、触摸动作

动作 常量
按下 MotionEvent.ACTION_DOWN
移动 MotionEvent.ACTION_MOVE
放开 MotionEvent.ACTION_UP

3、触摸监听器

  • 触摸监听器 - onTouchListener - 接口

4、触摸方法

  • onTouch()抽象 方法里,我们可以根据不同动作编写不同事件处理代码

5、触点个数与坐标

  • 通过MotionEvent对象的getX()getY()方法可以获得触摸点的坐标。如果是多点触摸,通过getPointerCount()获取触点个数,然后通过getX(pointerIndex)与getY(pointerIndex)获得某个触点的坐标。

6、安卓触摸事件处理机制

  • 触摸事件从view树的根节点开始一直传递到最下层,直到某个onTouchEvent()接收处理此事件。每个部分对触摸事件的处理过程如下:
    Activity的处理过程: Activity.dispatchTouchEvent()最先被调用,其作用是调用RootView(通常是一个ViewGroup)的dispatchTouchEvent(),即负责分发事件。ViewGroup中的dispatch会调用其他孩子的dispatchTouchEvent()。注意:Activity中的onTouchEvent()是整个View的触摸事件传递链条的终点,不过前提是整个过程中没有view的touchEvent对此事件感兴趣。
    View的处理过程: 检查是否有TouchListener()注册在这个View中,如果有则查看其是否想要消费此次事件,如果不消费事件,那么接下来该View的onTouchEvent()就要被调用了,如果未返回true,事件就会返回视图树的上一层。
  • ViewGroup的处理过程: 根据触摸发生的位置来判断哪些孩子可能会触发触摸事件,如果有重叠部分则按照被加入到ViewGroup中顺序的逆序来依次处理。ViewGroup可以引发一个中断(onInterceptTouchEvent())来强制把事件交给自己处理,当子视图的事件被剥夺时,子视图会收到ACTION_CANCEL事件,子视图可以用requestDisallowTouchIntercept()方法来屏蔽这个事件。
    由此可见,Touch事件是层层向下传递的,如果某个视图接收了此事件则接下来的视图就无法再次接收,但ViewGroup可以强制从子视图手中剥夺一个触摸事件。

二、案例演示:通过单点触摸移动米老鼠

1、创建安卓应用

2、准备图片素材

3、字符串资源文件

<resources><string name="app_name">通过触摸移动米老鼠</string>
</resources>

4、主布局资源文件

将约束布局改成线性布局,再添加一个图像控件显示米老鼠

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:id="@+id/root"android:background="@drawable/background"android:orientation="vertical"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid:id="@+id/iv_mickey"android:layout_width="100dp"android:layout_height="120dp"android:scaleType="fitXY"android:src="@drawable/mikey"/></LinearLayout>
  • 预览效果

5、主界面类实现功能

  • 声明变量和常量

  • 通过资源标识符获取控件实例

  • 让根布局获取焦点

  • 米老鼠图像控件的布局参数

  • 给线性根布局注册触摸监听器

  • 完整代码

package net.ls.movemickeybytouch;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {private ImageView ivMickey; //米老鼠图像控件private LinearLayout root; //线性根布局private LinearLayout.LayoutParams layoutParams; //布局参数private static final String TAG = "move_mickey_by_touch"; //标记常量@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);root=findViewById(R.id.root);ivmickey = findViewById(R.id.iv_mickey);//让根布局成为焦点root.setFocusable(true);root.requestFocus();//获取米老鼠图像控件的布局参数layoutParams = (LinearLayout.LayoutParams) ivmickey.getLayoutParams();// 给线性根布局注册触摸监听器,实现监听器接口,编写触摸事件代码root.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN://0,触点按下Log.d(TAG,"ACTION_DOWN("+event.getX()+","+event.getY()+")");break;case MotionEvent.ACTION_MOVE://2,触点移动Log.d(TAG,"ACTION_MOVE("+event.getX()+","+event.getY()+")");break;case MotionEvent.ACTION_UP://1,触点放开Log.d(TAG,"ACTION_UP("+event.getX()+","+event.getY()+")");break;}// 根据变化的触点坐标来更新米老鼠图像控件的布局参数layoutParams.leftMargin = (int) event.getX();layoutParams.topMargin = (int) event.getY();// 重新设置米老鼠图像控件的布局参数ivMickey.setLayoutParams(layoutParams);return true; // 设置为true,三个事件:down-->move-->up才会依次执行}});}
}
  • 查看效果

6、优化主界面类

  • 以上代码可完成移动米老鼠的任务,但触摸中心点在左上角,现在优化代码让触摸点在米老鼠中心
    不采用图像控件的布局参数,直接调用图像控件的setX()和setY()方法,分别传入触点横坐标event.getX()和纵坐标event.getY(),如果希望触点在米老鼠控件中央,那么分别传入event.getX() - ivMickey.getWidth() / 2与event.getY() - ivMickey.getHeight() / 2
package net.ls.movemickeybytouch;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {private ImageView ivmickey; //米老鼠图像控件private LinearLayout root; //线性根布局private LinearLayout.LayoutParams layoutParams; //布局参数private static final String TAG = "move_mickey_by_touch"; //标记常量@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);root=findViewById(R.id.root);ivmickey = findViewById(R.id.iv_mickey);//让根布局成为焦点root.setFocusable(true);root.requestFocus();//获取米老鼠图像控件的布局参数layoutParams = (LinearLayout.LayoutParams) ivmickey.getLayoutParams();// 给线性根布局注册触摸监听器,实现监听器接口,编写触摸事件代码root.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN://0,触点按下Log.d(TAG,"ACTION_DOWN("+event.getX()+","+event.getY()+")");break;case MotionEvent.ACTION_MOVE://2,触点移动Log.d(TAG,"ACTION_MOVE("+event.getX()+","+event.getY()+")");break;case MotionEvent.ACTION_UP://1,触点放开Log.d(TAG,"ACTION_UP("+event.getX()+","+event.getY()+")");break;}//设置米老鼠图像控件坐标ivmickey.setX(event.getX()-ivmickey.getWidth()/2);ivmickey.setY(event.getY()-ivmickey.getHeight()/2);return true;}});}
}

7、效果

三、案例演示:通过多点触摸缩放米老鼠

1、创建安卓应用

  • 基于Empty Activity模板创建安卓应用 - ZoomMickeyByTouch

2、准备图片素材

3、字符串资源文件

4、主布局资源文件

将约束布局改成线性布局,再添加一个图像控件显示米老鼠

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:id="@+id/root"android:background="@drawable/background"android:orientation="vertical"tools:context=".MainActivity"><ImageViewandroid:id="@+id/iv_mickey"android:layout_width="100dp"android:layout_height="120dp"android:src="@drawable/mickey"/></LinearLayout>

5、主界面类实现功能

  • 声明变量

  • 通过资源标识符获取控件实例,让根布局获取焦点,让根布局获取焦点

  • 给根布局注册触摸监听器

  • 完整代码

package net.ls.zoommickeybytouch;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {private LinearLayout root;private ImageView ivMickey;private float x1,y1;//第一个触点的坐标private float x2,y2;//第二个触点的坐标private float nextX1,nextY1;//第一个触点的下一次坐标private float nextX2,nextY2;//第二个触点的下一次坐标private float distance; //两个触点间的距离private float nextDistance;//两个触点的下一次距离private LinearLayout.LayoutParams layoutParams;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);root = findViewById(R.id.root);ivMickey = findViewById(R.id.iv_mickey);root.setFocusable(true);root.requestFocus();layoutParams = (LinearLayout.LayoutParams) ivMickey.getLayoutParams();//给根布局注册触摸监听器,实现触摸监听器接口,编写触摸事件方法root.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {//判断触点个数if (event.getPointerCount()==1){ //单点触摸 - 移动米老鼠layoutParams.leftMargin = (int)(event.getX() - ivMickey.getWidth()/2);layoutParams.topMargin = (int)(event.getY() - ivMickey.getHeight()/2);}else if (event.getPointerCount()==2){ //两点触摸 - 缩放米老鼠//判断触点动作switch (event.getAction()){case MotionEvent.ACTION_DOWN://获取第一个触点的坐标x1 = event.getX(0);y1 = event.getY(0);//获取第二个触点的坐标x2 = event.getX(1);x2 = event.getY(1);distance =(float) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));break;case MotionEvent.ACTION_MOVE://获取第一个触点下一次的坐标nextX1 = event.getX(0);nextY1 = event.getY(0);//获取第二个触点下一次的坐标nextX2 = event.getX(1);nextY2 = event.getY(1);//计算两个触点的下一次距离nextDistance = (float) Math.sqrt((nextX1-nextX2)*(nextX1-nextX2)+(nextY1-nextY2)*(nextY1-nextY2));break;case MotionEvent.ACTION_UP:break;}//修改米老鼠图像控件的布局参数if (nextDistance>distance){if (layoutParams.width<1000){layoutParams.width  = (int) (layoutParams.width*1.05);layoutParams.height = (int) (layoutParams.height*1.05);}} else {if (layoutParams.width>10) {layoutParams.width = (int) (layoutParams.width / 1.05);layoutParams.height = (int) (layoutParams.height / 1.05);}}//第一个触点坐标进行迭代x1 = nextX1;y1 = nextY1;x2 = nextX2;y2 = nextY2;distance=(float) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}ivMickey.setLayoutParams(layoutParams);return true;}});}
}

3.2 安卓触摸事件相关推荐

  1. 安卓学习笔记13:安卓触摸事件

    文章目录 零.学习目标 一.安卓触摸事件概述 1.触摸分类 2.触摸动作 3.触摸监听器 4.触摸方法 5.触点个数与坐标 二.安卓单点触摸 三.教学案例--通过单点触摸移动米老鼠 (一)运行效果 ( ...

  2. Android Studio笔记4.2 安卓触摸事件

    文章目录 一.前言 二.笔记4.2 安卓触摸事件 (一)安卓触摸事件概述 1.触摸分类 (1).单点触摸 (2).多点触摸 2.触摸动作 3.触摸监听器 4.触摸方法 5.触点个数与坐标 6.安卓触摸 ...

  3. 安卓讲课笔记4.2 安卓触摸事件

    文章目录 零.学习目标 一.导入新课 二.新课讲解 (一)安卓触摸事件概述 1.触摸分类 (1)单点触摸 (2)多点触摸 2.触摸动作 3.触摸监听器 4.触摸方法 5.触点个数与坐标 6.安卓触摸事 ...

  4. Android基础学习笔记13:安卓触摸事件触摸按键

    学习目标 了解安卓触摸动作 熟悉触摸监听器与方法 掌握单点触摸与多点触摸 在Android系统中,触摸是用户最常用,最基础的交互方式,只有弄通触摸事件在系统中的传递处理机制才能更好地增强用户的交互体验 ...

  5. Android Studio 笔记4.2 安卓触摸事件

    文章目录 一.前言 二.笔记4.2 安卓触摸事件 (一)安卓触摸事件概述 1.触摸分类 (1).单点触摸 (2).多点触摸 2.触摸动作 3.触摸监听器 4.触摸方法 5.触点个数与坐标 6.安卓触摸 ...

  6. Android Studio学习:安卓触摸事件

    (一)安卓触摸事件概述 1.触摸分类 (1)单点触摸 单点触控,只能识别和支持每次一个手指的触控.点击,若同时有两个以上的点被触碰,就不能做出正确反应.很多医院.图书馆等的大厅都有这种触控技术的电脑, ...

  7. 4.2 安卓触摸事件

    文章目录 一.简介 二.概述 (一)安卓触摸事件概述 1.触摸分类 (1)单点触摸 (2)多点触摸 2.触摸动作 3.触摸监听器 4.触摸方法 5.触点个数与坐标 6.安卓触摸事件处理机制 (二)案例 ...

  8. 4.3 安卓触摸事件

    文章目录 一.安卓触摸事件概述 1.触摸分类 (1)单点触摸 (2)多点触摸 2.触摸动作 3.触摸监听器 4.触摸方法 5.触点个数与坐标 6.安卓触摸事件处理机制 二.案例演示:通过单点触摸移动米 ...

  9. UE4 安卓触摸事件相关问题

    UE4在安卓端获取输入信息时候,似乎会把触摸事件和PC端的鼠标事件弄混在一起,导致出现一些奇怪的问题. 1. /* 安卓端会把触摸事件读取成PC端的鼠标事件,因为Turn和LookUp在PC端开发时候 ...

最新文章

  1. 【CV】Numpy|Python中矩阵和数组乘法及向量相关问题
  2. 使用命名空间:别名/导入
  3. 学习笔记CB006:依存句法、LTP、n元语法模型、N-最短路径分词法、由字构词分词法、图论、概率论...
  4. android 自定义图片上传,android自定义ImageView仿图片上传示例
  5. SAP UI5是如何从浏览器读取语言设置并按照优先级排序的
  6. 杀鸡焉用牛刀!放下Windbg,让dotnet-stack来快速定位死锁原因
  7. BZOJ4562: [Haoi2016]食物链
  8. 一步步编写操作系统 65 标准调用约定stdcall 汇编实战
  9. 项目:NMEA2000的数据格式解析
  10. JVM 运行时数据区域总结
  11. db2dual_db2 oracle 创建 序列 | 学步园
  12. 看病要排队 (hdu1873,优先队列)
  13. android 4g获取mac地址,Android手机获取Mac地址的几种方法
  14. thinkphp5.0 session驱动方式问题汇总
  15. matlab freqz m,freqz(freqz和freqs区别)
  16. 【数据库】数据字典表
  17. python 省份排序_Python常用的排序
  18. 树莓派直接连电脑热点
  19. LeetCode(数据库)- 2142. The Number of Passengers in Each Bus I
  20. 自学IT和接受IT培训两者的优缺点分析

热门文章

  1. Linux语音助手——Lewis小精灵(简陋版小度小度)
  2. php案例:字符串压缩解压
  3. 计算机丢失dll文件怎么弄,xxxxxx.dll文件丢失了怎么办?如何解决?
  4. 材料力学c语言程序,材料力学(I)五版课后习题答案完整版.pdf
  5. 【CTF-Reverse】花指令
  6. 谁在拿高薪?—IT业薪酬调查
  7. 删掉系统服务里边的tomcat7服务
  8. python pandas实现excel中的if 函数(一)
  9. 百行 HTML5 代码实现四种双人对弈游戏
  10. 360杀毒软件的快速崛起 告诉我们的一些道理