41. 【Android教程】Android 手势处理

作为忠实的 Android 系统用户,你应该会经常用到各种手势:点击、长按、双击、缩放、滑动、拖拽、返回等等,可以说丰富的手势可以让用户更加简洁方便的使用 App,甚至直接影响到 App 的使用体验。这些手势都是系统为我们提供的操作方式,今天来一起看看如何捕捉用户的手势输入。

1 手势检测工具

在前面的章节我们讲到过触摸事件:onTouch(),它是一切手势的开始,所以根据onTouch的几种事件类型我们可以判断出用户的各种手势,但是对于一些相对复杂的手势(比如缩放、旋转、双击等)判断起来会比较麻烦。不过这些都不用担心Android 系统为我们提供了一个叫GestureDetector的工具类,通过它我们可以轻松的接收到用户的各种复杂手势。

GestureDetector的使用方法非常简单,首先创建一个类继承自GestureDetector.SimpleOnGestureListener,然后覆写其中需要监听的事件方法,如下:

GestureDetector mGesture;
mGesture = new GestureDetector(this, new Gesture());
   
class Gesture extends GestureDetector.SimpleOnGestureListener{
   public boolean onSingleTapUp(MotionEvent ev) {
          // 处理单击事件
   }
   
   public void onLongPress(MotionEvent ev) {
          // 处理长按
   }
   
   public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
   float distanceY) {
          // 处理滑动手势
   }
   
   public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
   float velocityY) {
          // 处理快速滚动
   }
}

2 GestureListener 相关事件

Gesture 支持很多复杂的手势处理,基本上处理手势用它就没错了。这里挑几个最常见的进行详细的讲解,其余的也大同小异。

  • onDown: 触摸事件,同onTouch事件当中的ACTION_DOWN,所有手势的起点
  • onSingleTapUp: 单击
  • onLongPress: 长按
  • onScroll: 滚动
  • onFling: 手指快速滚动,并离开屏幕,在屏幕继续滚动的时候触发

3 手势的处理方式

在写好了第 1 小节的代码之后,关键就是去实现事件处理代码了,点击、长按等事件都比较好理解,这里以缩放手势为例讲解一下具体的手势处理逻辑。

3.1 缩放处理工具类

缩放的手势处理是通过ScaleGestureDetector来实现的,首先创建一个ScaleGestureDetector

ScaleGestureDetector scaleGestureDetector;
scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener());

构造器需要传入两个参数,一个是上下文 context,一个是缩放时间监听器。所以,在此之前我们还需要创建一个ScaleListener,然后覆写OnTouchEvent(MotionEvent e),并且在OnTouchEvent中将触摸事件传递给 ScaleGestureDetector,代码如下:

public boolean onTouchEvent(MotionEvent ev) {
   SGD.onTouchEvent(ev);
   return true;
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
   @Override
   public boolean onScale(ScaleGestureDetector detector) {
      float scale = detector.getScaleFactor();
      return true;
   }
}

3.2 手势处理中常用的系统方法

在处理手势的过程中,我们还会调用一些系统方法来辅助完成事件处理,主要有以下几个:

  • getEventTime():
    获取事件发生的时间戳
  • getFocusX():
    获取当前手势焦点的 X 轴坐标
  • getFocusY():
    获取当前手势焦点的 Y 轴坐标
  • getTimeDelta():
    获取两次缩放时间的时间差
  • isInProgress():
    判断当前是否正处理缩放过程中
  • onTouchEvent(MotionEvent event):
    接收系统触摸事件,并分发到相应的监听器中

4 手势处理示例

本节通过GestureDetector完成一个类似微信聊天中的大图缩放功能,即通过双指往外或者向内的手势来控制图片的放大、缩小。

4.1 编写布局文件

布局文件非常简单,核心就是一个 ImageView,用来承载我们缩放的目标图片。需要注意的是,这里要将图片的 scaleType设置成“matrix”,用于后续做缩放:

<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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="手势处理示例"
        android:textSize="35sp" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textview"
        android:layout_centerHorizontal="true"
        android:text="Android 教程"
        android:textColor="#ff7aff24"
        android:textSize="35dp" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_below="@+id/textView"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:scaleType="matrix"
        android:src="@drawable/avatar" />

</RelativeLayout>

4.2 手势处理逻辑编写

手势处理基本遵循上述逻辑,分为 4 步:

  • 第一步: 首先创建一个ScaleListener,覆写onScale方法来接收缩放手势;
  • 第二步: 然后创建ScaleGestureDetector,构造器传入 context 对象及刚刚创建的ScaleListener对象;
  • 第三步: 接着覆写onTouchEvent(MotionEvent ev),调用 ScaleGestureDetector 的onTouchEvent()方法,传入 MotionEvent,这样就把触摸事件传递给了ScaleGestureDetector,后续的整个缩放手势就全权交给ScaleGestureDetector来处理。
  • 第四步: 最后我们只需要在onScale()中完成我们的图片缩放逻辑即可。

代码如下,整体思路还是比较清晰的:


package com.emercy.myapplication;

import android.app.Activity;
import android.graphics.Matrix;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.ImageView;

public class MainActivity extends Activity {
    private ImageView iv;
    private Matrix matrix = new Matrix();
    private float scale = 1f;
    private ScaleGestureDetector mDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iv = findViewById(R.id.imageView);
        // 第2步:创建缩放手势检测器ScaleGestureDetector,用于检测缩放手势
        mDetector = new ScaleGestureDetector(this, new ScaleListener());
    }

    // 第3步:覆写onTouchEvent,将触摸事件传递给ScaleGestureDetector
    public boolean onTouchEvent(MotionEvent ev) {
        mDetector.onTouchEvent(ev);
        return true;
    }

    // 第1步:创建缩放监听器,用于接收缩放事件
    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            // 第4步:实现图片缩放逻辑
            scale *= detector.getScaleFactor();
            scale = Math.max(0.1f, Math.min(scale, 5.0f));
            matrix.setScale(scale, scale);
            iv.setImageMatrix(matrix);
            return true;
        }
    }
}

我们用双指向外或者向内滑动,就可以看到“照骗”会跟随我们的手势而放大/缩小,整个流程非常顺滑无污染,欢迎自行编译体验。

5 小结

本节介绍了一个非常强大的手势处理工具——GestureDetector,如果不使用它,我们需要自行监听onTouch事件,然后结合“DOWN”、“MOVE”、“UP”等等各种不同的 onTouch 事件组合起来才能检测出一些复杂的手势,这一切 GestureDetector 都帮助我们实现了。学完这一章,我们只需要按照几个简单的步骤就可以进行复杂手势的监听,从此可以释放双手,来创造更多复杂的事件让用户更加顺滑的使用了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/580200.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测评与广告双管齐下:敦煌网卖家如何结合自养号实现快速出单

敦煌网作为中国领先的B2B跨境电商平台&#xff0c;为卖家提供了广阔的市场和丰富的资源&#xff0c;但为何有些卖家却难以获得订单呢?下面的内容中&#xff0c;帮助卖家快速出单。 一、如何快速出单? 1、优化产品详情页&#xff1a;产品详情页是吸引买家下单的关键页面。卖…

Shell脚本编写-猜测当前系统是哪个发行版

1、编写脚本 该脚本会确定当前系统中可用的包管理器。同时还以已安装的软件包管理器为指导&#xff0c;猜测当前系统是基于哪个 Linux 发行版。 #!/bin/bash #检查当前系统的可用包管理器&#xff0c;以安装的软件包管理器为指导&#xff0c;猜测当前的系统是基于哪个Linux发行…

顺序表常用操作实现算法

查找操作 插入操作 删除操作 小结 参考附录模拟代码&#xff1a; #include <iostream> const int maxn200; //顺序表 typedef struct{//定义静态类型 int num[maxn];// 装数数组 int len;//记录长度 }sqlist; typedef struct{//定义动态类型 int *num;int len; }sqlist…

XYCTF 2024

本博客仅为记录解题的过程&#xff01; MISC game google识图 XYCTF{Papers Please} 熊博士 XYCTF{liu_ye_mei_you_xiao_jj} 疯狂大杂烩&#xff01;九转功成 在远古时期&#xff0c;修仙过程被分为&#xff1a;炼气、筑基、结丹、元婴、化神、炼虚、合体、大乘、渡劫等九…

MOM是什么?

数字化时代&#xff0c;制造企业纷纷引入信息化系统工具来实现数字化转型升级&#xff0c;你可能对OA、CRM、ERP、MES耳熟能详&#xff0c;说起MOM&#xff0c;你了解吗&#xff1f;今天小编跟你一起认识下它。 MOM是什么&#xff1f; MOM&#xff08;制造运营管理&#xff09…

泰迪智能科技受邀参加2024年粤港澳大湾区产教融合技能人才培养联盟理事会会议

4月24日下午&#xff0c;2024年粤港澳大湾区产教融合技能人才培养联盟&#xff08;以下简称联盟&#xff09;理事会会议在白云区成功举办。 会议由广州市人力资源和社会保障局、广州市发展和改革委员会、广州市教育局、广州市工业和信息化局、广州市总工会等单位指导&#xff…

面经总结(二)(数据库)

数据库常识&#xff1a; 1、数据库系统包含什么&#xff1f; 包含了数据库、数据库管理系统、数据库管理员和应用程序。 数据库&#xff08;DB)&#xff1a;顾名思义是存放数据的仓库&#xff0c;实现数据的持久化。 数据库管理系统&#xff08;DBMS)&#xff1a;类似于操作系…

winrar压缩时排除指定目录排除所有子目录下的目录名称排除所有不需要的目录减小备份体积移除中间目录惊喜

winrar排除指定目录所有指定目录 说明(废话)解决方1. 打开 WinRAR。2. 导航到你要压缩的目录&#xff0c;然后选择该目录中的文件或文件夹。3. 点击“添加”按钮。4. 在弹出的“压缩文件名和参数”窗口中&#xff0c;切换到“文件”标签页。5. 在“文件”标签页中&#xff0c;找…

Topaz Gigapixel AI v7.1.2激活版:智能图像增强与放大

Topaz Gigapixel AI&#xff0c;这款基于人工智能技术的图像处理软件&#xff0c;以其卓越的功能和高效的性能&#xff0c;为图像处理领域注入了新的活力。 Topaz Gigapixel AI v7.1.2激活版下载 作为一款专注于图像增强与放大的软件&#xff0c;Topaz Gigapixel AI利用深度学习…

数据结构11:二叉树的链式结构

文章目录 快速创建链式二叉树二叉树的遍历前序、中序、后序层序 二叉树的基本操作二叉树的节点个数二叉树叶节点的个数二叉树第k层结点个数二叉树查找值为x的结点 二叉树基础oj练习单值二叉树检查两颗树是否相同对称二叉树二叉树的前序遍历另一颗树的子树 二叉树的创建和销毁二…

哈密顿函数和正则方程

9-2 哈密顿函数和正则方程_哔哩哔哩_bilibili 拉格朗日函数是广义坐标和广义速度的函数 哈密顿函数是广义坐标和广义动量的函数 拉格朗日函数经过勒让德变换得到哈密顿函数

设计普遍逼近的深度神经网络:一阶优化方法

论文地址&#xff1a;https://ieeexplore.ieee.org/document/10477580 传统的基于优化的神经网络设计方法通常从一个具有显式表示的目标函数出发&#xff0c;采用特定的优化算法进行求解&#xff0c;再将优化迭代格式映射为神经网络架构&#xff0c;例如著名的 LISTA-NN 就是利…

无人零售与传统便利店的竞争优势

无人零售与传统便利店的竞争优势 成本控制 • 无人零售 显著降低了人力成本&#xff0c;无需支付店员薪资和相关福利&#xff0c;且通过智能化管理减少能源消耗与维护费用&#xff0c;尤其在高租金和高人流区域效益突出。 • 传统便利店 则承担较高的人员开支&#xff0c;…

linux安装maven

linux安装maven 先安装java环境&#xff0c;比如笔者自己的这个 http://t.csdnimg.cn/mNpFO 现在版本已经来到了3.9.6 1、下载这个maven的link链接 2、创建文件夹 mkdir -p /usr/local/maven #为了可以上传成功(也可以不用。) chmod -R 777 /usr/local/maven #这个可以使用…

【深入理解神经网络:预测和评估】

文章目录 前言环境准备数据导入和处理数据归一化神经网络的创建与训练预测与评估结果可视化应用结论 前言 在这篇博客文章中&#xff0c;我们将深入研究利用神经网络进行数据预测和性能评估的过程。我们将详解在MATLAB环境下使用的一个例子&#xff0c;该例子展示了如何使用MAT…

学pyhton的第二十二天

原文链接&#xff1a;Python 图形化界面设计&#xff08;Tkinter&#xff09; - 简书 (jianshu.com) 相关博客链接 接第十八天Tkinter的内容&#xff1a; 单选按钮&#xff08;控件&#xff1a;Radiobutton&#xff09;&#xff1a; 除共有属性外&#xff0c;还具有显示文本…

uniapp对uni.request()的封装以及使用

官方文档 uni.request(OBJECT) | uni-app官网 (dcloud.net.cn) uni.request参数 参数名说明url是写api地址的data是用来传值的对于 GET 方法&#xff0c;会将数据 转换为 query string。例如 { name: name, age: 18 } 转换后的结果是 namename&age18。对于 POST 方法且 …

BUUCTF:Basic 解析(一)

一、Linux Labs 打开靶场 F12 源代码啥也没有&#xff0c;但是题目给出了 ssh 连接的用户名密码端口号及主机&#xff0c;推测应该是要连接&#xff0c;打开 XShell 连接 设置用户名及密码 连接成功&#xff0c;随后找到 flag 二、BUU LFI COURSE 1 打开靶场 F12 检查源代码…

微火快报:全域外卖服务商是什么?如何成为全域外卖服务商?

最近&#xff0c;互联网行业又出现了一个新名词——全域外卖服务商&#xff0c;很多人都预感到它可能是下一个风口&#xff0c;却因为不了解概念和找不到入局的途径而止步不前。那么本期&#xff0c;我们就来重点讲一讲全域外卖服务商的概念、发展前景以及入局的途径。 所谓的全…

电脑进水不用怕,教你几招恢复如初!

电脑进水是一种常见但严重的问题&#xff0c;可能会导致电脑损坏&#xff0c;甚至无法正常使用。在遇到电脑进水的情况下&#xff0c;正确的处理方式至关重要&#xff0c;可以最大程度地减少损害并提高修复成功的可能性。本文将介绍三种解决电脑进水问题的方法&#xff0c;帮助…
最新文章