Android 触摸屏交互之手势监听

简介: Android 触摸屏交互之手势监听

效果图

20200619112128154.gif


前言


2020年,智能手机大行其道,相信不会还有人用着老式的按键手机了吧,而智能手机最大的交互就是手机屏幕,其次的就是音量操作、生物识别(指纹+人脸+瞳孔)、说白了用的最多的是手机的屏幕,屏幕与用户之前进行交互,比如打开一个app你是不是要点击屏幕上某一个?有人说我可以用语音去打开,但是你没有想过语音其实只是帮你执行了点击,在手机上不管是玩游戏还是看电影或者是搞学习,都是要使用手机屏幕的,所以你知道屏幕交互有多么重要吗?


正文


屏幕的交互当然首先是触摸,说道触摸就是有一个手势监听,这个是Google起的名字,你不用手难道用脚吗?


下面可以新建一个项目,在MainActivity中实现两个监听


20200619104243900.png


GestureDetector.OnGestureListener//手势监听
GestureDetector.OnDoubleTapListener//双击监听


实现这两个监听之后,会创建好几个方法,这里我会一个一个说明


onDown

  /**
     * 当用户在屏幕上按下时会触发该方法,但在移动或抬起手指时不会触发
     * @param e
     * @return
     */
    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }


onShowPress

  /**
     * 当用户在屏幕上按下,并且既没有移动有没有抬起手指时,会触发该方法。
     * 一般通过该方法告知用户他们的动作已经被识别到了,你可以 高亮某个元素来提醒他们
     * @param e
     */
    @Override
    public void onShowPress(MotionEvent e) {
    }


onSingleTapUp


  /**
     * 当用户在屏幕上轻击时(通常是指点击屏幕的时间很短)会触发该方法
     * @param e
     * @return
     */
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }


onScroll


  /**
     * 在屏幕上发起滚动的手势时会触发该方法
     * @param e1        第一个按下开始滚动的动作事件
     * @param e2        触发当前这个方法的移动动作的事件
     * @param distanceX 触发onScroll方法期间的X上的滚动距离
     * @param distanceY 触发onScroll方法期间的Y上的滚动距离
     * @return
     */
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }


onLongPress

  /**
     * 记得设置detector.setIsLongpressEnabled(true);,否则长按不会触发
     * 当用户在屏幕上持续地长按时会触发该方法
     *
     * @param e
     */
    @Override
    public void onLongPress(MotionEvent e) {
    }


onFling

  /**
     * 当用户在屏幕上持续地按下并且有“抛”的动作时,会触发该方法。对于该事件的理解,
     * 你可以体会一下按住一个图标然后把它扔到某个地方的感觉。
     *
     * @param e1        第一个按下的动作事件
     * @param e2        触发当前这个方法的“猛扔”动作的事件
     * @param velocityX 触发onFling方法期间X轴上的移动速度
     * @param velocityY 触发onFling方法期间Y轴上的移动速度
     * @return
     */
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false;
    }


onSingleTapConfirmed

  /**
     * 当用户在屏幕上单击是会触发此方法,与上面的onSingleTapUp方法不同的地方在于,
     * 该方法只会在监听器确定了用户在第一次单击后不会触发双击事件时才会被触发。
     *
     * @param e
     * @return
     */
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        return true;
    }


onDoubleTap

  /**
     * 当用户在屏幕上双击时会触发此方法。这里的按下动作事件指的时双击中的第一次触击。
     *
     * @param e
     * @return
     */
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        return false;
    }


onDoubleTapEvent

  /**
     * 在双击事件发生时会触发此方法,包括了按下、移动和抬起事件。
     *
     * @param e
     * @return
     */
    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }


在Android系统中,每一次手势交互都会依照以下顺序执行


1,接触接触屏一刹那,触发一个MotionEvent事件。


2.该事件被OnTouchListener监听,在其onTouch()方法里获得该MotionEvent对象。


3.通过GestureDetector(手势识别器)转发次MotionEvent对象至OnGestureListener。


4.OnGestureListener获得该对象,听根据该对象封装的的信息,做出合适的反馈。

在Android中,是由GestureDetector类来负责手势的检测,每一个GestureDetector类的实例都代表一个手势监听器。在创建手势监听器时需要一个类OnGestureListener例。


下面就来实践一下,为了使整个效果更直观,我修改了一下布局


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        app:navigationIcon="@mipmap/icon_clear" />
    <LinearLayout
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/tv_result"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="初学者-Study"
            android:textColor="#000"
            android:textSize="24sp" />
    </LinearLayout>
</LinearLayout>


里面用到了一个图标icon_clear.png


20200619105659793.png

回到MainActivity

  GestureDetector detector;//声明一个手势检测器对象
    private TextView tvResult, tvTest;
    Toolbar toolbar;
    String result = "";


然后在onCreate()中

    tvResult = findViewById(R.id.tv_result);
        toolbar = findViewById(R.id.toolbar);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                result = "初学者-Study";
                tvResult.setText(result);
                result = "";
            }
        });
        detector = new GestureDetector(this, this);//实例化这个手势检测器对象
        detector.setIsLongpressEnabled(true);//打开长触摸


然后就是具体的使用了                                          

  //绑定手势监听  这是前置条件
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return detector.onTouchEvent(e);
    }


然后就可以在各个方法中进行数据的处理和显示了

  /**
     * 当用户在屏幕上按下时会触发该方法,但在移动或抬起手指时不会触发
     *
     * @param e
     * @return
     */
    @Override
    public boolean onDown(MotionEvent e) {
        result += "onDown\n";
        tvResult.setText(result);
        return false;
    }
    /**
     * 当用户在屏幕上按下,并且既没有移动有没有抬起手指时,会触发该方法。
     * 一般通过该方法告知用户他们的动作已经被识别到了,你可以 高亮某个元素来提醒他们
     *
     * @param e
     */
    @Override
    public void onShowPress(MotionEvent e) {
        result += "onShowPress\n";
        tvResult.setText(result);
    }
    /**
     * 当用户在屏幕上轻击时(通常是指点击屏幕的时间很短)会触发该方法
     *
     * @param e
     * @return
     */
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        result += "onSingleTapUp\n";
        tvResult.setText(result);
        return false;
    }
    /**
     * 在屏幕上发起滚动的手势时会触发该方法
     *
     * @param e1        第一个按下开始滚动的动作事件
     * @param e2        触发当前这个方法的移动动作的事件
     * @param distanceX 触发onScroll方法期间的X上的滚动距离
     * @param distanceY 触发onScroll方法期间的Y上的滚动距离
     * @return
     */
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        if (distanceY >= 0) {//上滑
            result += "onScroll - Up\n";
            tvResult.setText(result);
        } else {//下滑
            result += "onScroll - Down\n";
            tvResult.setText(result);
        }
        return false;
    }
    /**
     * 记得设置detector.setIsLongpressEnabled(true);,否则长按不会触发
     * 当用户在屏幕上持续地长按时会触发该方法
     *
     * @param e
     */
    @Override
    public void onLongPress(MotionEvent e) {
        result += "onLongPress\n";
        tvResult.setText(result);
    }
    /**
     * 当用户在屏幕上持续地按下并且有“抛”的动作时,会触发该方法。对于该事件的理解,
     * 你可以体会一下按住一个图标然后把它扔到某个地方的感觉。
     *
     * @param e1        第一个按下的动作事件
     * @param e2        触发当前这个方法的“猛扔”动作的事件
     * @param velocityX 触发onFling方法期间X轴上的移动速度
     * @param velocityY 触发onFling方法期间Y轴上的移动速度
     * @return
     */
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        result += "onFling\n";
        tvResult.setText(result);
        return false;
    }
    /**
     * 当用户在屏幕上单击是会触发此方法,与上面的onSingleTapUp方法不同的地方在于,
     * 该方法只会在监听器确定了用户在第一次单击后不会触发双击事件时才会被触发。
     *
     * @param e
     * @return
     */
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        result += "onSingleTapConfirmed\n";
        tvResult.setText(result);
        return true;
    }
    /**
     * 当用户在屏幕上双击时会触发此方法。这里的按下动作事件指的时双击中的第一次触击。
     *
     * @param e
     * @return
     */
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        result += "onDoubleTap\n";
        tvResult.setText(result);
        return false;
    }
    /**
     * 在双击事件发生时会触发此方法,包括了按下、移动和抬起事件。
     *
     * @param e
     * @return
     */
    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        result += "onDoubleTapEvent\n";
        tvResult.setText(result);
        return false;
    }


运行看一下效果


点击屏幕

20200619110655761.gif


长触摸

20200619110855208.gif


双击屏幕

20200619111112161.gif


向上滑动

20200619111304322.gif


向下滑动

2020061911151789.gif


这就是基本的事件逻辑了,可以根据自己的需求进一步做处理,比如音量屏幕左边上滑时调节亮度,右边上滑时调节音量,这都是通过在onScroll方法中做处理实现的。OK,就是这样了


相关文章
|
6月前
|
安全 API Android开发
Android网络和数据交互: 解释Retrofit库的作用。
Android网络和数据交互: 解释Retrofit库的作用。
72 0
|
1月前
|
Java Linux Android开发
移动应用开发与操作系统的交互:深入理解Android和iOS
在数字时代,移动应用成为我们日常生活的一部分。本文将深入探讨移动应用开发的核心概念、移动操作系统的工作原理以及它们如何相互作用。我们将通过实际代码示例,展示如何在Android和iOS平台上创建一个简单的“Hello World”应用,并解释其背后的技术原理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和知识。
|
6月前
|
JSON Android开发 数据格式
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
84 2
|
3月前
|
XML Android开发 UED
"掌握安卓开发新境界:深度解析AndroidManifest.xml中的Intent-filter配置,让你的App轻松响应scheme_url,开启无限交互可能!"
【8月更文挑战第2天】在安卓开发中,scheme_url 通过在`AndroidManifest.xml`中配置`Intent-filter`,使应用能响应特定URL启动或执行操作。基本配置下,应用可通过定义特定URL模式的`Intent-filter`响应相应链接。
110 12
|
3月前
|
JSON Android开发 数据格式
Android项目架构设计问题之实现交互响应的结构化处理如何解决
Android项目架构设计问题之实现交互响应的结构化处理如何解决
18 0
|
5月前
|
JavaScript 前端开发 Android开发
kotlin安卓在Jetpack Compose 框架下使用webview , 网页中的JavaScript代码如何与native交互
在Jetpack Compose中使用Kotlin创建Webview组件,设置JavaScript交互:`@Composable`函数`ComposableWebView`加载网页并启用JavaScript。通过`addJavascriptInterface`添加`WebAppInterface`类,允许JavaScript调用Android方法如播放音频。当页面加载完成时,执行`onWebViewReady`回调。
|
6月前
|
安全 物联网 测试技术
构建未来:Android与IoT设备的无缝交互深入探索软件自动化测试的未来趋势
【5月更文挑战第30天】在物联网(IoT)技术快速发展的当下,Android系统因其开放性和广泛的用户基础成为了连接智能设备的首选平台。本文将探讨如何通过现代Android开发技术实现智能手机与IoT设备的高效、稳定连接,并分析其中的挑战和解决方案。我们将深入挖掘Android系统的底层通信机制,提出创新的交互模式,并通过实例演示如何在Android应用中集成IoT控制功能,旨在为开发者提供一套可行的指导方案,促进IoT生态系统的进一步发展。
|
6月前
|
XML JSON API
转Android上基于JSON的数据交互应用
转Android上基于JSON的数据交互应用
42 1
|
6月前
|
Java Android开发
Android桌面快捷方式图标生成与删除 使用Intent与launcher交互
Android桌面快捷方式图标生成与删除 使用Intent与launcher交互
110 1
|
SQL 人工智能 移动开发
Android应用启动流程:从启动到可交互的过程解析
Android应用启动流程:从启动到可交互的过程解析