HarmonyOS鸿蒙Next中ArkUI识别手指的触摸方向失败
HarmonyOS鸿蒙Next中ArkUI识别手指的触摸方向失败 也不是说完全失败就是两个if判断放在一起就只能识别一个
这是方法

可是就运行这个方法就能识别手指的左或右

这是我的完整的代码
import {框架, 布局} from './框架';
@Entry
@ComponentV2
struct Index_o2 {
@Local 框架长宽:框架=new 框架(0, 0);
@Local 上组件:布局=new 布局(0, 0)
@Local 中组件:布局=new 布局(0, 0)
@Local 下组件:布局=new 布局(0, 0)
build() {
Column(){
上组件({上组件:this.上组件})
中组件({中组件:this.中组件})
下组件({下组件:this.下组件})
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center) // 水平居中
.justifyContent(FlexAlign.Center)
.onSizeChange((框架长宽旧值: SizeOptions, 框架长宽新值: SizeOptions) => {
this.上组件.宽=框架长宽新值.width as number*1;
this.上组件.高=框架长宽新值.height as number*0.1;
this.中组件.宽=框架长宽新值.width as number*1;
this.中组件.高=框架长宽新值.height as number*0.65;
this.下组件.宽=框架长宽新值.width as number*1;
this.下组件.高=框架长宽新值.height as number*0.25;
})
}
}
@ComponentV2
struct 上组件{
@Param @Require 上组件!:布局
build() {
Row(){
//上
}
.backgroundColor(Color.Red)
.width(this.上组件.宽)
.height(this.上组件.高)
.onTouch((手指触摸事件:TouchEvent) => {
})
}
}
@ComponentV2
struct 中组件{
@Param @Require 中组件!:布局
@Local 左组件:布局=new 布局(0, 0)
@Local 右组件:布局=new 布局(0, 0)
build() {
Row(){
左组件({左组件:this.左组件,右组件:this.右组件})
右组件({右组件:this.右组件,左组件:this.左组件})
}
.border({
width: {top:2, bottom:2},
color: Color.Black,
style: BorderStyle.Dashed
})
.width(this.中组件.宽)
.height(this.中组件.高)
.onSizeChange((框架长宽旧值: SizeOptions, 框架长宽新值: SizeOptions) => {
this.左组件.宽=框架长宽新值.width as number *0.4
this.左组件.初始宽=框架长宽新值.width as number *0.4
this.左组件.高=框架长宽新值.height as number
this.左组件.设置父布局宽(框架长宽新值.width as number)
this.右组件.宽=框架长宽新值.width as number *0.6
this.右组件.初始宽=框架长宽新值.width as number *0.6
this.右组件.高=框架长宽新值.height as number
this.右组件.设置父布局宽(框架长宽新值.width as number)
})
}
}
@ComponentV2
struct 左组件{
@Param @Require 左组件!:布局
@Param @Require 右组件!:布局
build() {
Row(){
//左
}
.backgroundColor(Color.Green)
.border({
width: {right:2},
color: Color.Black,
style: BorderStyle.Dashed
})
.width(this.左组件.宽)
.height(this.左组件.高)
.onMouse((事件) => {
})
/*
.onTouch((手指触摸事件)=>{
let 获取的手指:TouchObject[]=手指触摸事件.touches
if(获取的手指[0].type==TouchType.Down&&this.左组件.手指触摸的第一次甄别==0){
this.左组件.手指触摸初的始位置=获取的手指[0].x
this.左组件.手指触摸的第一次甄别=1;
}
if(this.左组件.组件边缘判别('右', 20)){
if(获取的手指[0].type==TouchType.Move){
this.左组件.宽=获取的手指[0].x+(this.左组件.初始宽-this.左组件.手指触摸初的始位置)
this.右组件.宽=this.左组件.返回父布局宽()-this.左组件.宽
}
}
if(获取的手指[0].type==TouchType.Up){
this.左组件.手指触摸的第一次甄别=0;
this.左组件.初始宽=this.左组件.宽;
}
})
*/
}
}
@ComponentV2
struct 右组件{
@Param @Require 右组件!:布局
@Param @Require 左组件!:布局
build() {
Row(){
//右
}
.backgroundColor(Color.Orange)
.width(this.右组件.宽)
.height(this.右组件.高)
.onTouch((手指触摸事件)=>{
let 获取的手指:TouchObject[]=手指触摸事件.touches
if(获取的手指[0].type==TouchType.Down&&this.右组件.手指触摸的第一次甄别==0){
this.右组件.手指触摸初的始位置=获取的手指[0].x
this.右组件.手指触摸的第一次甄别=1;
this.右组件.横轴=获取的手指[0].x
this.右组件.纵轴=获取的手指[0].y
}
/*
if(this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y)==='左'){
console.error('左')
}
if(this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y)==='右'){
console.error('右')
}
*/
console.error(this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y))
/*
if(this.右组件.组件边缘判别('左', 20)&&this.右组件.组件大小限制('宽', this.右组件.返回父布局宽()*0.8, this.右组件.返回父布局宽()*0.2)){
if(获取的手指[0].type==TouchType.Move){
this.左组件.宽=(this.左组件.初始宽+获取的手指[0].x)-this.右组件.手指触摸初的始位置
this.右组件.宽=this.左组件.返回父布局宽()-this.左组件.宽
}
}
*/
if(获取的手指[0].type==TouchType.Up){
this.右组件.手指触摸的第一次甄别=0;
this.左组件.初始宽=this.左组件.宽;
}
})
}
}
@ComponentV2
struct 下组件{
@Param @Require 下组件!:布局
build() {
Row(){
//下
}
.backgroundColor(Color.Brown)
.width(this.下组件.宽)
.height(this.下组件.高)
.onTouch((手指触摸事件:TouchEvent) => {
let 获取的手指:TouchObject[]=手指触摸事件.touches
if(获取的手指[0].type==TouchType.Down&&this.下组件.手指触摸的第一次甄别==0){
this.下组件.手指触摸初的始位置=获取的手指[0].y
this.下组件.手指触摸的第一次甄别=1;
}
if(获取的手指[0].type==TouchType.Up){
this.下组件.手指触摸的第一次甄别=0;
}
if(获取的手指[0].type==TouchType.Move){
}
})
}
}
@ObservedV2
export class 框架 {
@Trace 宽:number=0;
@Trace 初始宽:number=0;
@Trace 高:number=0;
@Trace 初始高:number=0;
@Trace 手指触摸的第一次甄别:number=0;
@Trace 手指触摸初的始位置:number=0;
constructor(宽: number, c: number) {
this.宽 = 宽;
this.高 = 宽;
}
public 布局边缘甄别():boolean{
return false;
}
}
export class 布局 extends 框架 {
private 父布局宽:number=0;
private 父布局高:number=0;
public 横轴:number=0;
public 纵轴:number=0;
public 方位真假:boolean=false;
constructor(宽: number, 高: number) {
super(宽, 高)
}
public 设置父布局宽(宽:number):void{
this.父布局宽=宽;
}
public 设置父布局高(高:number):void{
this.父布局高=高;
}
public 返回父布局宽():number{
return this.父布局宽
}
public 返回父布局高():number{
return this.父布局高
}
public 组件大小限制(限制的宽或高:string, 限制的最大值:number, 限制的最小值:number):boolean{
if(限制的宽或高==='宽'){
if(this.宽>限制的最小值&&this.宽<限制的最大值){
return true;
}
}
if(限制的宽或高==='高'){
if(this.高>限制的最小值&&this.高<限制的最大值){
return true;
}
}
return false;
}
public 组件边缘判别(组件边缘方位:string,阈值:number):boolean{
if(组件边缘方位==='左'){
if(this.手指触摸初的始位置>0&&this.手指触摸初的始位置<阈值){
return true;
}
}
/*
if(this.左组件.手指触摸初的始位置>(this.左组件.初始宽-10)&&this.左组件.手指触摸初的始位置<this.左组件.初始宽){
if(获取的手指[0].type==TouchType.Move){
this.左组件.宽=获取的手指[0].x+(this.左组件.初始宽-this.左组件.手指触摸初的始位置)
this.右组件.宽=this.左组件.返回父布局宽()-this.左组件.宽
}
}
*/
if(组件边缘方位==='右'){
if(this.手指触摸初的始位置>(this.初始宽-阈值)&&this.手指触摸初的始位置<this.初始宽){
return true;
}
/*
if(this.右组件.手指触摸初的始位置>0&&this.右组件.手指触摸初的始位置<10){
if(获取的手指[0].type==TouchType.Move){
this.左组件.宽=(this.左组件.初始宽+获取的手指[0].x)-this.右组件.手指触摸初的始位置
this.右组件.宽=this.左组件.返回父布局宽()-this.左组件.宽
}
}
*/
}
return false;
}
public 识别手指滑动的方位(横轴或纵轴:string, 获取手指的横轴:number, 获取手指的纵轴:number):string{
if(横轴或纵轴==='横轴'){
if(this.横轴<获取手指的横轴){
this.横轴=获取手指的横轴
return '右'
}
if(this.横轴>获取手指的横轴){
this.横轴=获取手指的横轴
return '左'
}
}
if(横轴或纵轴==='纵轴'){
if(this.纵轴<获取手指的纵轴){
this.纵轴=获取手指的纵轴
return '下'
}
if(this.纵轴>获取手指的纵轴){
this.纵轴=获取手指的纵轴
return '上'
}
}
return '不动'
}
}
哪位大神帮我看看是怎么个事
更多关于HarmonyOS鸿蒙Next中ArkUI识别手指的触摸方向失败的实战教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,定位问题是由于调用了两次识别手指滑动方法。第一个if判断调用识别手指滑动方法时已经将获取手指的横轴的值赋值给this.横轴,导致在第二个if判断调用识别手指滑动方法时由于this.横轴===获取手指的横轴始终成立,不符合所有if场景,产生了第二个if判断没有运行的错觉。无需调用两次识别手指滑动方法,只需调用一次识别手指滑动方法获取返回值,然后进行if判断即可。
更多关于HarmonyOS鸿蒙Next中ArkUI识别手指的触摸方向失败的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,如以上方案无法解决问题请及时反馈。
太厉害了,中英混合编程,没见到你的帖子之前还不知道鸿蒙支持中文编程了。
是不是对中文编程有深深的鄙视😒,
这倒没有,我一般用拼音+外语混合编程,因为中文汉字编程以及中文路径之前在很多语言不支持,习惯了。
谢谢大神在百忙之中回答我的问题,是我大总了没有在问题中详细的说明我的想法,让大神白白的浪费了许多时间,对不起。。。。。。
我的意思是在右组件中运行这一段代码

可以完全实现我想要的效果
你看。。。。当我在右组件中向左滑动手指在log中就能打印 “左”

当我在右组件中向右滑动手指在log中就能打印 “右”

当我在右组件中向按信手指不动在log中就能打印 “不动”

可是当我运行这一段代码效果就完全不一样了

按道理来说它们运行的都是同一个方法
this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y)
可为什么只能判断出向“右”滑动手指
向“左”滑动手指 就判断不出来
你看 当我向右滑动在log中就能显示出来

当我向左滑动在log中就不能显示出来
也就是说第二个 if()语句 没有执行

按道理 右 和 左 都能判断的
去掉您的代码中的注释,触摸方向识别失败的根本原因在于只调用了单一轴向的判断,而您可能期望同时识别横轴和纵轴的方向变化。下面详细分析问题所在,并给出改进建议。
1. 当前代码的逻辑分析
在 右组件 的 onTouch 事件中,您只调用了一次 识别手指滑动的方位 方法,且参数固定为 '横轴':
console.error(this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y))
因此,每次触摸事件(Down、Move、Up)都仅比较横轴坐标,并更新 this.右组件.横轴。纵轴坐标 this.右组件.纵轴 仅在 Down 时被记录,之后从未更新,所以纵轴方向永远无法被识别。
识别手指滑动的方位 方法内部有两个 if 分支(横轴和纵轴),但执行哪个分支完全取决于传入的第一个参数。您只传入了 '横轴',因此纵轴分支永远不会执行,这就是“两个 if 判断放在一起却只能识别一个”的直接原因。
2. 隐含的其他问题
即使您尝试在同一个 onTouch 中同时调用两次(一次 '横轴',一次 '纵轴'),也会遇到状态更新的问题:
- 第一次调用(横轴)会更新
this.右组件.横轴为当前x。 - 第二次调用(纵轴)会更新
this.右组件.纵轴为当前y。
但若两次调用顺序固定,且每次 Move 事件都执行,逻辑上是可行的。不过,您目前的代码中并没有这样做,所以纵轴方向始终未参与比较。
此外,下组件 的 onTouch 中虽然记录了 Down 和 Up,但完全没有调用任何方向识别逻辑,所以也无法识别上下滑动。
3. 改进建议
方案一:分别调用两次,分别获取横纵方向
在 onTouch 的 Move 分支中,分别调用两次方法,并分别处理返回的方向:
if (获取的手指[0].type == TouchType.Move) {
let 横向方向 = this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y);
let 纵向方向 = this.右组件.识别手指滑动的方位('纵轴', 获取的手指[0].x, 获取的手指[0].y);
console.log(`横向:${横向方向},纵向:${纵向方向}`);
}
注意:Down 事件中必须同时记录横轴和纵轴的初始值,Move 中每次都要更新两个轴的值。
方案二:重构识别方法,一次性返回两个方向
修改 识别手指滑动的方位 方法,使其同时比较并更新横纵坐标,返回一个包含两个方向的对象:
public 识别手指滑动方向(x: number, y: number): { x: '左'|'右'|'不动', y: '上'|'下'|'不动' } {
let xDir = '不动';
let yDir = '不动';
if (this.横轴 < x) {
xDir = '右';
this.横轴 = x;
} else if (this.横轴 > x) {
xDir = '左';
this.横轴 = x;
}
if (this.纵轴 < y) {
yDir = '下';
this.纵轴 = y;
} else if (this.纵轴 > y) {
yDir = '上';
this.纵轴 = y;
}
return { x: xDir, y: yDir };
}
然后在 onTouch 的 Move 中调用一次即可获得两个方向。
4. 额外注意事项
- 触摸事件中
touches[0]代表第一个触摸点,但如果您支持多点触控,需要更复杂的处理。 - 您的
布局类继承自框架,且框架中的手指触摸的第一次甄别等属性在多个组件实例中共享,但当前逻辑是每个组件独立使用自己的实例,所以没有共享问题。 - 在
右组件的Up事件中,您重置了this.右组件.手指触摸的第一次甄别并更新了this.左组件.初始宽,这看起来像是用于调整左右组件宽度,但方向识别失败与此无关。
大神我回错了回成了我自己了 不好意思 本来是要回你的我想让你帮我看看
在HarmonyOS Next中,ArkUI识别触摸方向失败通常与手势事件处理有关。请检查PanGesture或TouchEvent事件回调中的offsetX和offsetY参数,这些参数用于计算移动方向。确保在组件上正确绑定了手势事件,如.gesture(PanGesture(...).onActionUpdate((event: GestureEvent) => { ... }))。方向判断逻辑需基于这些偏移值的正负和大小来实现。
问题出在识别手指滑动的方位方法的逻辑上。你每次调用这个方法时,都会更新this.横轴的值,这导致连续判断时方向识别失效。
具体分析:
- 在
右组件的onTouch中,你连续调用了两次识别手指滑动的方位方法(虽然第二次被注释了)。 - 第一次调用时,如果手指向右滑动,方法返回"右",但同时
this.横轴被更新为新的x坐标。 - 紧接着第二次调用时,由于
this.横轴已经是新的x坐标,与传入的获取手指的横轴相同,方法返回"不动"。
解决方案:
- 不要在
识别手指滑动的方位方法内部更新this.横轴和this.纵轴。 - 改为在TouchType.Move事件中计算方向,并单独更新坐标值。
修正后的方法示例:
public 识别手指滑动的方位(横轴或纵轴:string, 获取手指的横轴:number, 获取手指的纵轴:number):string{
if(横轴或纵轴==='横轴'){
if(this.横轴 < 获取手指的横轴){
return '右'
}
if(this.横轴 > 获取手指的横轴){
return '左'
}
}
if(横轴或纵轴==='纵轴'){
if(this.纵轴 < 获取手指的纵轴){
return '下'
}
if(this.纵轴 > 获取手指的纵轴){
return '上'
}
}
return '不动'
}
然后在onTouch事件中:
.onTouch((手指触摸事件)=>{
let 获取的手指:TouchObject[]=手指触摸事件.touches
if(获取的手指[0].type==TouchType.Down&&this.右组件.手指触摸的第一次甄别==0){
this.右组件.手指触摸初的始位置=获取的手指[0].x
this.右组件.手指触摸的第一次甄别=1;
this.右组件.横轴=获取的手指[0].x
this.右组件.纵轴=获取的手指[0].y
}
if(获取的手指[0].type==TouchType.Move){
let 方向 = this.右组件.识别手指滑动的方位('横轴', 获取的手指[0].x, 获取的手指[0].y)
console.error(方向)
// 更新坐标值
this.右组件.横轴=获取的手指[0].x
this.右组件.纵轴=获取的手指[0].y
}
if(获取的手指[0].type==TouchType.Up){
this.右组件.手指触摸的第一次甄别=0;
this.左组件.初始宽=this.左组件.宽;
}
})
这样修改后,方向识别就能正常工作了。

