arkui-x开发中遇到的各种奇怪focus问题
近期遇到的各种奇怪问题,做一个记录:
参考在线文档,使用onFocus、onBlur写法,这也是一般习惯性的写法,如下
Stack() {
Text('取消')
.TextExtendRegularWithRadius(this.displayInfo, this.isFocusBt1)
}
.onClick(() => {
if (this.isFocusBt1) {
...
}
})
.attributeModifier(this.isFocusBt1 ? this.modifier : this.modifierNormal)
.focusCfgAndActWithBt1()
.margin({ right: this.displayInfo.getHeight(40) })
......
@Styles
focusCfgAndActWithBt1() {
.focusable(true)
.focusOnTouch(true)
.onFocus(() => {
this.isFocusBt1 = true
})
.onBlur(() => {
this.isFocusBt1 = false
})
}
1、如果不定义onClick,focus效果不生效,click相当于提供了一个类似于文本输入的焦点
2、focusable开关必须定义
3、focusOnTouch必须定义
4、defaultFocus根据情况来使用,这里没有用,如果使用,页面打开默认focus到“取消”
5、focusCfgAndActWithBt1 @Styples是devEco的重构提取写法,ide支持右键和菜单操作
评价:上面写法对元素比较少的,且对外无交互的页面,是没有问题的。支持键盘tab,不好的地方在于,需要点击触发变焦。
复杂情况下,上面写法可能导致各种问题。
如:主页面通过某个动作触发custom dialog弹窗,在弹窗中操作可触发二次弹窗,之后可再触发一个promptAction
要求:每次弹窗取消,focus不变,这个能够支持。
第二次弹窗,触发了一个删除动作,需要focus自动指向下一个。测试发现,删除触发弹窗的原始元素,主页面处于失去焦点状态,会自动找一个前面的元素设置焦点,这个元素的选择感觉是随机的。如果程序主动在二次弹窗结束后,设置下一个元素焦点。则会同时出现两个元素有焦点。
鼠标点击一下系统设置的有焦点元素,再点其他,才能取消焦点。否则会一直处于两焦点并存状态。
尝试使用focusControl.requestFocus主动设置焦点也没用。系统的默认行为也无法取消,可能是删除数据,通过@State引发@Builder重新渲染,渲染过程中,系统自动选择了一个历史元素,设置了焦点。
解决方法,不使用onFocus、onBlur,改为使用onHover,即鼠标悬停状态下,自动设置focus标识,上面问题就会好很多。这样的作法给用户的感觉也会好很多,但是不支持键盘的tab键。
.onHover((isHover?: boolean) => {
if (isHover) {
// this.appCtrInfoListList[info.index].focus = true
this.isFocusBt1 = true;
this.isFocusBt2 = false;
} else {
// this.appCtrInfoListList[info.index].focus = false
this.isFocusBt1 = false;
}
})
另一个奇怪问题,当页面有多个元素时,需要给每个元素一个focus标识,用bool变量记录。
相对list元素,就采用一个bool数组。
当元素增加了其他的变量时,自然就像封装一个class,把focus以及其他信息都放进去。
但是采用class的数组就会使得focus不生效

如上图,改成红色的写法,就不生效。而this.isFocusItem[info.index]写法就是正常的。
更多推荐



所有评论(0)