HarmonyOS实战—滑动事件的坐标和返回值
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.
- HarmonyOS文章专栏:https://blog.csdn.net/qq_41684621/category_10128500.html
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
-
139
KeyEvent类 Android.View.KeyEvent类中定义了一系列的常量和方法,用来描述Android中的按键事件。 和返回键有关的常量和方法有。 KeyEvent.KEYCODE_BACK: 表示key类型为返回键 KeyEvent....
-
47
一、背景介绍 在业务安全领域,滑动验证码已经是国内继,传统字符型验证码之后的标配。众所周知,打码平台和机器学习这两种绕过验证码的方式,已经是攻击者很主流的思路,不再阐述。本文介...
-
13
Shared Element Transitions with RecyclerView to ViewPager + 滑动返回 2017-03-142020-06-25 实现朋友圈图片查看的转场动画+滑动返回,RecyclerView to ViewPager。
-
14
2020-12-27 / 语义分割
-
3
Systrace 流畅性实战 2 :案例分析 - MIUI 桌面滑动卡顿分析
-
6
2015年6月7日全屏返回手势自 iOS7 之后,Apple 增加了屏幕边缘右划返回交互的支持,再配合上 UINavigationController 的交互式动画,pop 到上一级页面的操作变的非常顺畅和丝滑,从此,我很少再使用点击左上角导航栏上的...
-
0
1. 双击事件 双击事件和单击事件有些类似,也有四种实现的方法 1.通过id找到组件。 2.给按钮组件设置双击事件。 3.本类实现DoubleClickedListener接口重写。 4.重写onDoubleCli...
-
3
Activity简单几步支持向右滑动返回 – Android开发中文站你的位置:Android开发中文站 > Android开发 >
-
5
uni-app关闭系统侧边滑动返回的方法总汇更新日期: 2022-03-18阅读量: 359标签: uniapp分享扫一...
-
1
实现效果图 本随笔只是记录一下大概的实现思路...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK