5

HarmonyOS实战—滑动事件的坐标和返回值

 3 years ago
source link: https://my.oschina.net/xdr630/blog/5152611
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1. 滑动事件获取手指位置

  • 滑动事件的三个动作:

在这里插入图片描述

  • 获取手指的位置就涉及到坐标的概念,通过获取到 x、y、z就可以缺任意一个点的位置

在这里插入图片描述

  • 手机中的坐标:

在这里插入图片描述

  • 除了 x、y轴,还有z轴,在鸿蒙手机当中,完整的坐标如下,是一个立体的三维体系,但平时z轴用的非常少,一般情况只需考虑x、y轴就行了。

在这里插入图片描述

  • 结合滑动事件的三个动作坐标来分析滑动

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2. 获取按下时手指的位置(坐标)

  • 获取的这些数据其实都被鸿蒙操作系统封装到TouchEvent这个动作对象当中,通过动作去调用getPointerPosition 方法,需要传递一个值。鸿蒙系统支持多手指的操作,比如:可以用两个手指对图片进行放大或缩小,所以在getPointerPosition需要传递一个索引,一个手指操作传递的值为0,表示要获取的是第一个手指的位置,他的位置也是封装成一个对象,再用坐标对象分别获取到x、y坐标。
	//获取按下时手指的位置(坐标)
	MmiPoint point = touchEvent.getPointerPosition(0);
	//x、y表示按下时手指的位置
	float x = point.getX();
	float y = point.getY();
	text1.setText(x + "---" + y);

3. 实现案例:把按下、移动、松开的位置分别设置到文本框当中

  • 新建项目:ListenerApplication4

ability_main

  • 采用默认生成的Text文本内容,在此基础上给DirectionalLayout布局和Text组件分别加上id
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    ohos:id="$+id:dl"
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:alignment="center"
    ohos:orientation="vertical">

    <Text
        ohos:id="$+id:text1"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:background_element="$graphic:background_ability_main"
        ohos:layout_alignment="horizontal_center"
        ohos:text="$string:mainability_HelloWorld"
        ohos:text_size="40vp"
        />

</DirectionalLayout>

MainAbilitySlice

  • 采用当前类作为实现类接口的方式编写
package com.xdr630.listenerapplication.slice;

import com.xdr630.listenerapplication.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.multimodalinput.event.TouchEvent;

public class MainAbilitySlice extends AbilitySlice implements Component.TouchEventListener {

    Text text1 = null;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);

        //1.先找到整个布局对象
        DirectionalLayout dl = (DirectionalLayout) findComponentById(ResourceTable.Id_dl);
        text1 = (Text) findComponentById(ResourceTable.Id_text1);

        //2.给整个布局添加滑动事件
        //当我们在整个布局滑动的时候,就会调用本类中的onTouchEvent方法
        //在按下 移动、松开的过程,代码会不断去调用本类中的 onTouchEvent方法
        dl.setTouchEventListener(this);
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        //参数1:component表示滑动的组件(布局也是一种组件,所以也可以用component表示布局对象)
        //实际上此时代表的就是DirectionalLayout布局对象,这个布局是铺满整个屏幕的
        //参数2:touchEvent表示动作对象(按下、滑动、抬起)

        //获取当前手指对屏幕进行操作(按下、滑动、抬起)
        int action = touchEvent.getAction();
        // 1:表示按下操作
        // 2:表示松开操作
        // 3. 表示滑动/移动操作

        if (action == TouchEvent.PRIMARY_POINT_DOWN){
            //只要写按下时需要运行的代码即可
            //获取按下时手指的位置(坐标)
            MmiPoint point = touchEvent.getPointerPosition(0);
            //x、y表示按下时手指的位置
            float x = point.getX();
            float y = point.getY();
            text1.setText(x + "---" + y);
        }else if (action == TouchEvent.POINT_MOVE){
            //移动或滑动
            //获取按下时手指的位置(坐标)
            MmiPoint point = touchEvent.getPointerPosition(0);
            //x、y表示按下时手指的位置
            float x = point.getX();
            float y = point.getY();
            text1.setText(x + "---" + y);
        }else if (action == TouchEvent.PRIMARY_POINT_UP){
            //松开或抬起
           //获取按下时手指的位置(坐标)
            MmiPoint point = touchEvent.getPointerPosition(0);
            //x、y表示按下时手指的位置
            float x = point.getX();
            float y = point.getY();
            text1.setText(x + "---" + y);
        }
        return true;
    }
}

在这里插入图片描述

  • 按下并且移动鼠标时,坐标数值就会随着鼠标的移动而变化

在这里插入图片描述

4. 根据手指的位置来确定是上、下、左、右哪个滑动

  • 首先把按下时的 x、y 移动onTouchEvent方法外面去,因为如果没有移动外面去,当第一次按下的时候就会调用onTouchEvent方法,接着就会调用按下时的位置,获取到x、y坐标并设置到文本框里,设置完以后整个方法就么有了,获取完后就从内存中消失了,按下时的x、y的值也就消失了。
  • 所以在方法外定义x、y,因为获取到的是小数,要定义为float类型

在这里插入图片描述

  • 移动的位置就不需要获取了,只要按下和松开的位置进行对比就可以判断是上、下、左、右的哪个滑动了

在这里插入图片描述

在这里插入图片描述

  • 把上述代码进行如下修改
  • onTouchEvent方法外定义x、y的位置

在这里插入图片描述

	//记录按下手指的位置
    float startX = 0;
    float startY = 0;
  • onTouchEvent方法里的if判断作出如下修改
	if (action == TouchEvent.PRIMARY_POINT_DOWN){
	    MmiPoint point = touchEvent.getPointerPosition(0);
	    //x、y表示按下时手指的位置
	    startX = point.getX();
	    startY = point.getY();
	}else if (action == TouchEvent.POINT_MOVE){
		//移动的位置就不需要获取了,只要按下和松开的位置进行对比就可以判断是上、下、左、右的哪个滑动了
	}else if (action == TouchEvent.PRIMARY_POINT_UP){
	    //松开或抬起
	    MmiPoint point = touchEvent.getPointerPosition(0);
	    //x、y表示按下时手指的位置
	    float endX = point.getX();
	    float endY = point.getY();
	    //拿着按下时的位置跟松开时手指的位置进行比对
	    if (endX > startX){
	        text1.setText("右滑");
	    }else if (endX < startX){
	        text1.setText("左滑");
	    }else if (endY > startY){
	        text1.setText("下滑");
	    }else if (endY < startY) {
	        text1.setText("上滑");
	    }

在这里插入图片描述

  • 按下后鼠标从左往右移动,然后松开

在这里插入图片描述

  • 按下后鼠标从右往左移动,然后松开

在这里插入图片描述

  • 按下后鼠标从上往下移动,然后松开

在这里插入图片描述

  • 按下后鼠标从下往上移动,然后松开

在这里插入图片描述

  • 此时还有一个明显的bug,那就是当鼠标从最最左边上面的点到最右边下面的点,既有下滑也有右滑

5. 滑动事件bug处理

  • 当我们滑动的时候,滑的不直,滑的有点斜
  • 斜着滑,可以对Y变化的范围(斜的幅度)做一个规定,假设变化为100,如果你滑的时候变化了超过了100,那就认为这是一个无效的滑动,如果没有超过,才认为这是一个有效的滑动

在这里插入图片描述

  • 解决bug: 添加个绝对值,防止两者大小相减出现复数
	if (endX > startX && Math.abs(endY - startY) < 100){
	    text1.setText("右滑");
	}else if (endX < startX && Math.abs(endY - startY) < 100){
	    text1.setText("左滑");
	}else if (endY > startY && Math.abs(endX - startX) < 100){
	    text1.setText("下滑");
	}else if (endY < startY && Math.abs(endX - startX) < 100) {
	    text1.setText("上滑");
	}
  • 运行,当斜的幅度超过100时,就会认为这是个无效的滑动,就不会显示这个滑动的动作
  • 但运行斜的幅度不超过100,就会显示正确的滑动效果

在这里插入图片描述

6. onTouchEvent方法的返回值

  • 如果为true,表示所有的动作都会触发当前方法并执行对应的代码
  • 如果为false,表示只有一个动作会触发当前方法并执行对应的代码,后续的动作就不会触发当前方法
  • 滑动事件的三个动作:按下——>移动——>松开,当为true时,这三个动作都会执行onTouchEvent方法并执行下面对应的代码。为false时,只有按下这个动作会触发 onTouchEvent方法并执行下面对应的代码

7. 验证onTouchEvent方法的返回值对滑动事件三个动作的影响

  • 上述代码不变,onTouchEvent方法改动如下:
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {

        count++;

        int action = touchEvent.getAction();
        
        if (action == TouchEvent.PRIMARY_POINT_DOWN){
            text1.setText("按下");
        }else if (action == TouchEvent.POINT_MOVE){
            text1.setText("移动");
        }else if (action == TouchEvent.PRIMARY_POINT_UP){
            text1.setText("松开");
        }
        //如果为true,表示所有的动作都会触发当前方法并执行对应的代码
        //如果为false,表示只有一个动作会触发当前方法并执行对应的代码,后续的动作就不会触发当前方法了
        return false;
    }
  • 运行后,当按下后再移动、松开。显示的文本依赖不变,说明返回值为false,只有按下这个动作会触发 onTouchEvent方法并执行下面对应的代码,移动、松开都不会执行onTouchEvent方法。

在这里插入图片描述

  • 把上面的返回值改为true,运行后。发现文本显示的值都会随着按下、移动、松开的动作进行变化

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 所以滑动事件一般都写true

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK