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

系统 OpenHarmony
获取的这些数据其实都被鸿蒙操作系统封装到TouchEvent这个动作对象当中,通过动作去调用getPointerPosition 方法,需要传递一个值。

[[415874]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

Table of Contents

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

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

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

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

5. 滑动事件bug处理

6. onTouchEvent方法的返回值

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

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

  • 滑动事件的三个动作:

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

  • 手机中的坐标:

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

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

 

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

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

  1. //获取按下时手指的位置(坐标) 
  2. MmiPoint point = touchEvent.getPointerPosition(0); 
  3. //x、y表示按下时手指的位置 
  4. float x = point.getX(); 
  5. float y = point.getY(); 
  6. text1.setText(x + "---" + y); 

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

  • 新建项目:ListenerApplication4

ability_main

  • 采用默认生成的Text文本内容,在此基础上给DirectionalLayout布局和Text组件分别加上id
  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     ohos:id="$+id:dl" 
  4.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  5.     ohos:height="match_parent" 
  6.     ohos:width="match_parent" 
  7.     ohos:alignment="center" 
  8.     ohos:orientation="vertical"
  9.  
  10.     <Text 
  11.         ohos:id="$+id:text1" 
  12.         ohos:height="match_content" 
  13.         ohos:width="match_content" 
  14.         ohos:background_element="$graphic:background_ability_main" 
  15.         ohos:layout_alignment="horizontal_center" 
  16.         ohos:text="$string:mainability_HelloWorld" 
  17.         ohos:text_size="40vp" 
  18.         /> 
  19.  
  20. </DirectionalLayout> 

MainAbilitySlice

  • 采用当前类作为实现类接口的方式编写
  1. package com.xdr630.listenerapplication.slice; 
  2.  
  3. import com.xdr630.listenerapplication.ResourceTable; 
  4. import ohos.aafwk.ability.AbilitySlice; 
  5. import ohos.aafwk.content.Intent; 
  6. import ohos.agp.components.Component; 
  7. import ohos.agp.components.DirectionalLayout; 
  8. import ohos.agp.components.Text; 
  9. import ohos.multimodalinput.event.TouchEvent; 
  10.  
  11. public class MainAbilitySlice extends AbilitySlice implements Component.TouchEventListener { 
  12.  
  13.     Text text1 = null
  14.  
  15.     @Override 
  16.     public void onStart(Intent intent) { 
  17.         super.onStart(intent); 
  18.         super.setUIContent(ResourceTable.Layout_ability_main); 
  19.  
  20.         //1.先找到整个布局对象 
  21.         DirectionalLayout dl = (DirectionalLayout) findComponentById(ResourceTable.Id_dl); 
  22.         text1 = (Text) findComponentById(ResourceTable.Id_text1); 
  23.  
  24.         //2.给整个布局添加滑动事件 
  25.         //当我们在整个布局滑动的时候,就会调用本类中的onTouchEvent方法 
  26.         //在按下 移动、松开的过程,代码会不断去调用本类中的 onTouchEvent方法 
  27.         dl.setTouchEventListener(this); 
  28.     } 
  29.  
  30.     @Override 
  31.     public void onActive() { 
  32.         super.onActive(); 
  33.     } 
  34.  
  35.     @Override 
  36.     public void onForeground(Intent intent) { 
  37.         super.onForeground(intent); 
  38.     } 
  39.  
  40.     @Override 
  41.     public boolean onTouchEvent(Component component, TouchEvent touchEvent) { 
  42.         //参数1:component表示滑动的组件(布局也是一种组件,所以也可以用component表示布局对象) 
  43.         //实际上此时代表的就是DirectionalLayout布局对象,这个布局是铺满整个屏幕的 
  44.         //参数2:touchEvent表示动作对象(按下、滑动、抬起) 
  45.  
  46.         //获取当前手指对屏幕进行操作(按下、滑动、抬起) 
  47.         int action = touchEvent.getAction(); 
  48.         // 1:表示按下操作 
  49.         // 2:表示松开操作 
  50.         // 3. 表示滑动/移动操作 
  51.  
  52.         if (action == TouchEvent.PRIMARY_POINT_DOWN){ 
  53.             //只要写按下时需要运行的代码即可 
  54.             //获取按下时手指的位置(坐标) 
  55.             MmiPoint point = touchEvent.getPointerPosition(0); 
  56.             //x、y表示按下时手指的位置 
  57.             float x = point.getX(); 
  58.             float y = point.getY(); 
  59.             text1.setText(x + "---" + y); 
  60.         }else if (action == TouchEvent.POINT_MOVE){ 
  61.             //移动或滑动 
  62.             //获取按下时手指的位置(坐标) 
  63.             MmiPoint point = touchEvent.getPointerPosition(0); 
  64.             //x、y表示按下时手指的位置 
  65.             float x = point.getX(); 
  66.             float y = point.getY(); 
  67.             text1.setText(x + "---" + y); 
  68.         }else if (action == TouchEvent.PRIMARY_POINT_UP){ 
  69.             //松开或抬起 
  70.            //获取按下时手指的位置(坐标) 
  71.             MmiPoint point = touchEvent.getPointerPosition(0); 
  72.             //x、y表示按下时手指的位置 
  73.             float x = point.getX(); 
  74.             float y = point.getY(); 
  75.             text1.setText(x + "---" + y); 
  76.         } 
  77.         return true
  78.     } 
  • 运行:

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

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

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

所以在方法外定义x、y,因为获取到的是小数,要定义为float类型

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

  • 右滑

  • 下滑

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

  1. //记录按下手指的位置 
  2.     float startX = 0; 
  3.     float startY = 0; 
  • 在onTouchEvent方法里的if判断作出如下修改
  1. if (action == TouchEvent.PRIMARY_POINT_DOWN){ 
  2.     MmiPoint point = touchEvent.getPointerPosition(0); 
  3.     //x、y表示按下时手指的位置 
  4.     startX = point.getX(); 
  5.     startY = point.getY(); 
  6. }else if (action == TouchEvent.POINT_MOVE){ 
  7.     //移动的位置就不需要获取了,只要按下和松开的位置进行对比就可以判断是上、下、左、右的哪个滑动了 
  8. }else if (action == TouchEvent.PRIMARY_POINT_UP){ 
  9.     //松开或抬起 
  10.     MmiPoint point = touchEvent.getPointerPosition(0); 
  11.     //x、y表示按下时手指的位置 
  12.     float endX = point.getX(); 
  13.     float endY = point.getY(); 
  14.     //拿着按下时的位置跟松开时手指的位置进行比对 
  15.     if (endX > startX){ 
  16.         text1.setText("右滑"); 
  17.     }else if (endX < startX){ 
  18.         text1.setText("左滑"); 
  19.     }else if (endY > startY){ 
  20.         text1.setText("下滑"); 
  21.     }else if (endY < startY) { 
  22.         text1.setText("上滑"); 
  23.     } 
  • 运行:

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

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

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

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

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

5. 滑动事件bug处理

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

  • 解决bug:

添加个绝对值,防止两者大小相减出现复数

  1. if (endX > startX && Math.abs(endY - startY) < 100){ 
  2.         text1.setText("右滑"); 
  3.     }else if (endX < startX && Math.abs(endY - startY) < 100){ 
  4.         text1.setText("左滑"); 
  5.     }else if (endY > startY && Math.abs(endX - startX) < 100){ 
  6.         text1.setText("下滑"); 
  7.     }else if (endY < startY && Math.abs(endX - startX) < 100) { 
  8.         text1.setText("上滑"); 
  9.     } 
  • 运行,当斜的幅度超过100时,就会认为这是个无效的滑动,就不会显示这个滑动的动作
  • 但运行斜的幅度不超过100,就会显示正确的滑动效果

6. onTouchEvent方法的返回值

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

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

上述代码不变,onTouchEvent方法改动如下:

  1. public boolean onTouchEvent(Component component, TouchEvent touchEvent) { 
  2.  
  3.         count++; 
  4.  
  5.         int action = touchEvent.getAction(); 
  6.          
  7.         if (action == TouchEvent.PRIMARY_POINT_DOWN){ 
  8.             text1.setText("按下"); 
  9.         }else if (action == TouchEvent.POINT_MOVE){ 
  10.             text1.setText("移动"); 
  11.         }else if (action == TouchEvent.PRIMARY_POINT_UP){ 
  12.             text1.setText("松开"); 
  13.         } 
  14.         //如果为true,表示所有的动作都会触发当前方法并执行对应的代码 
  15.         //如果为false,表示只有一个动作会触发当前方法并执行对应的代码,后续的动作就不会触发当前方法了 
  16.         return false
  17.     } 

运行后,当按下后再移动、松开。显示的文本依赖不变,说明返回值为false,只有按下这个动作会触发 onTouchEvent方法并执行下面对应的代码,移动、松开都不会执行onTouchEvent方法。

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

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

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-08-06 09:47:01

鸿蒙HarmonyOS应用

2023-08-07 14:52:33

WindowsExplorer进程

2021-08-13 11:31:23

HTTP

2010-07-21 10:32:05

Perl函数返回值

2009-12-07 11:11:41

WCF返回值

2009-12-25 17:21:13

ADO返回值

2010-07-09 13:20:37

HART协议

2010-03-02 16:50:34

WCF返回值

2022-02-23 13:31:26

RVO编译器优化

2009-11-17 16:16:59

PHP递归函数

2009-09-07 03:07:11

C# Main方法

2021-08-02 14:37:36

鸿蒙HarmonyOS应用

2011-07-19 17:33:53

存储过程javaibatis

2009-12-08 15:52:10

WCF回调

2021-12-19 23:58:51

Golang语言返回值

2010-03-17 17:37:17

Java线程返回值

2022-07-06 07:08:58

CPythonPython返回值

2022-01-17 06:58:35

C语言函数错误码

2009-12-23 10:34:15

ADO.NET 批处理

2010-07-20 11:37:00

Perl函数返回值
点赞
收藏

51CTO技术栈公众号