39. 【Android教程】触摸事件分发

简介: 39. 【Android教程】触摸事件分发

用户在使用 Andriod 系统的时候会不断的和我们的 App 进行各种类型的交互(类似点击、滑动等等),“事件”就是一个非常有效的用来收集用户行为的方式。在前面章节有提到过:Android 系统采用一个先进先出(FIFO)队列来维护一个事件 List。在每个事件出列的时候,Android 系统会根据一定的规则对这些事件做分发,我们可以通过接收这些事件来对用户的操作进行相应的处理。

1. 事件处理相关概念

  • Event Listeners Registration:
  • 事件监听器注册。在接收事件之前完成注册,目的是告诉系统当前需要监听某个事件,从而在事件触发的时候系统会回调已注册接口中的方法。

  • Event Listeners:
  • 事件监听器。顾名思义,当某个事件被用户行为触发的时候,系统会回调所有已注册相应事件监听器的回调方法,从而完成事件的分发。

  • Event Handlers:
  • 事件处理。当事件发生时,系统会回调我们注册过的接口,所以可以在回调方法中对事件进行处理

2. 触摸事件类型

一次完整的触摸事件是从手指触摸屏幕一直到离开屏幕,这个过程可能非常短暂,但是对于 Android 系统而言发生了很多状态的切换,常用的主要有以下几种:

  • ACTION_DOWN:
  • 手指刚接触到的状态
  • ACTION_POINTER_DOWN:
  • 在第一个状态之后其他的点发生了触摸
  • ACTION_MOVE:
  • 手指触摸滑动
  • ACTION_POINTER_UP:
  • 除了第一个触摸点以外的触摸点离开屏幕
  • ACTION_UP:
  • 第一个接触的点离开屏幕
  • ACTION_CANCEL:
  • 滑动时移动到无效区域

3. 触摸事件监听方法

3.1 注册触摸监听器

为了能够顺利接收到以上事件,并进行相应处理,我们需要在事件发生之前完成注册,方法如下:

public boolean onTouchEvent(MotionEvent ev){
 
   switch(ev.getAction()){
      case MotionEvent.ACTION_DOWN:{
         break;
      }
   
      case MotionEvent.ACTION_MOVE:{
         break;
      }
      return true;
   }
}

3.2 获取触摸坐标

在接收到各个状态的事件之后,我们需要从中获取当前的触摸/滑动坐标,如下:

1. float x = ev.getX();
2. float y = ev.getY();

4. 触摸事件示例

在实际开发中,大多数时候我们需要监听的是DOWNMOVE以及UP三个事件,我们可以在DOWN事件中获取到触摸的起点,然后在MOVE过程中获取并不断追踪用户的滑动坐标,最后在UP事件中获取终点进而结束本次 Touch 事件。

4.1 布局文件

首先编写布局文件,我们需要 4 个 TextView,分别用来显示触摸起点的 X 轴、Y 轴坐标,以及滑动时的 X 轴、Y 轴偏移量,最后创建一个 View 用作触摸事件的接收源。内容非常简单,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:padding="20dp"
    android:transitionGroup="true"
    tools:context=".MainActivity">
 
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Android 事件处理"
        android:textSize="35dp" />
 
    <TextView
        android:id="@+id/down_x"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"
        android:layout_alignStart="@+id/title"
        android:layout_marginTop="30dp"
        android:hint="点击的X轴坐标"
        android:textColor="@color/colorPrimary" />
 
    <TextView
        android:id="@+id/down_y"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/down_x"
        android:layout_alignStart="@+id/down_x"
        android:layout_marginTop="10dp"
        android:hint="点击的Y轴坐标"
        android:textColor="@color/colorPrimary" />
 
    <TextView
        android:id="@+id/move_x"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/down_y"
        android:layout_alignStart="@+id/down_y"
        android:layout_marginTop="60dp"
        android:hint="移动位置的X轴坐标"
        android:textColor="@color/colorPrimaryDark" />
 
    <TextView
        android:id="@+id/move_y"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/move_x"
        android:layout_alignStart="@+id/move_x"
        android:hint="移动位置的Y轴坐标"
        android:textColor="@color/colorPrimaryDark" />
 
    <TextView
        android:id="@+id/touch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="点我开始滑动"
        android:textColor="#ff5480ff"
        android:textSize="35sp" />
</RelativeLayout>

4.2 触摸事件的注册、监听以及处理

在 MainActivity 中我们对 id 为 touch 的 TextView 注册触摸监听器,然后在DOWN中获取触摸起点,并写在对应的 TextView 中;随后在MOVE中实时获取滑动偏移量,也在对应的 TextView 中进行实时更新,代码如下:


 
package com.emercy.myapplication;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
 
public class MainActivity extends Activity {
    float xAxis = 0f;
    float yAxis = 0f;
 
    float downXAxis = 0f;
    float downYAxis = 0f;
 
    TextView downX, downY, moveX, moveY;
    TextView touch;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        downX = findViewById(R.id.down_x);
        downY = findViewById(R.id.down_y);
        moveX = findViewById(R.id.move_x);
        moveY = findViewById(R.id.move_y);
 
        touch = findViewById(R.id.touch);
 
        // 1、注册触摸监听器
        touch.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final int actionPeformed = event.getAction();
 
                // 2、判断当前触摸状态
                switch (actionPeformed) {
                    case MotionEvent.ACTION_DOWN: {
                        // 3、在不同状态中进行触摸事件处理
                        downXAxis = event.getX();
                        downYAxis = event.getY();
 
                        downX.setText("按下的位置横坐标:" + downXAxis);
                        downY.setText("按下的位置纵坐标:" + downYAxis);
                        break;
                    }
 
                    case MotionEvent.ACTION_MOVE: {
                        final float x = event.getX();
                        final float y = event.getY();
 
                        final float dx = x - downXAxis;
                        final float dy = y - downYAxis;
 
                        xAxis += dx;
                        yAxis += dy;
 
                        moveX.setText("移动距离的横坐标:" + xAxis);
                        moveY.setText("移动距离的纵坐标:" + yAxis);
                        break;
                    }
                }
                return true;
            }
        });
    }
}

编译运行,效果如下:

触摸左下角的“点我开始滑动”,当前触摸的坐标就会在 TextView 中展示了,然后滑动手指,随着滑动的偏移量的变化,也会在 TextView 中进行同步更新。

5. 小结

本节讲解了触摸事件的分发处理方式,首先介绍了事件处理的几个常用概念及一次触摸事件中切换的几种状态,然后讲述了触摸事件处理的几个重要方法,最后用一个完整例子演示了触摸事件的监听处理。这个是继onClick()事件后最常用的一个事件,也是绝大多数事件分发的基础事件,因为各种交互事件都是从触摸开始的,所以大家即使用的不多也一定要掌握使用方法及其中的基本原理。

相关文章
|
8月前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
5493 2
|
8月前
|
缓存 网络协议 安全
49. 【Android教程】HTTP 使用详解
49. 【Android教程】HTTP 使用详解
130 1
|
3月前
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
517 4
|
3月前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
8月前
|
XML 存储 JSON
51. 【Android教程】JSON 数据解析
51. 【Android教程】JSON 数据解析
192 2
|
8月前
|
存储 API 文件存储
47. 【Android教程】SharedPreferences 存储
47. 【Android教程】SharedPreferences 存储
87 2
|
8月前
|
存储 安全 大数据
46. 【Android教程】文件存储
46. 【Android教程】文件存储
84 3
|
8月前
|
存储 编解码 Android开发
58. 【Android教程】音频录制:MediaRecord
58. 【Android教程】音频录制:MediaRecord
84 2
|
8月前
|
设计模式 Android开发
44. 【Android教程】广播接收器:Broadcast Receiver
44. 【Android教程】广播接收器:Broadcast Receiver
197 2
|
8月前
|
安全 数据库 Android开发
45. 【Android教程】内容提供者 - Content Provider
45. 【Android教程】内容提供者 - Content Provider
106 2

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Android 13 SystemUI 启动流程
  • 1
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    23
  • 2
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    21
  • 3
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    52
  • 4
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    35
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    70
  • 6
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    111
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
    29
  • 8
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
    264
  • 9
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
    75
  • 10
    【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
    36