【小源笔记】第二期 | 如何为应用适配焦点控制 原创
前言
在一些依靠遥控器操作的设备例如智慧屏,按键走焦是主要的交互方式,通过焦点可以告诉用户当前聚焦的位置
当前支持焦点控制的组件有Button、Text、Image、List、Grid
如何适配
除Button还有Toggle组件外,其他组件默认都是不可获焦的,一个组件想要获得焦点,需要focusable
属性等于 true
。以系统settings应用为例,首页是一个List列表容器,要给每个ListItem子项添加焦点事件,只需要给ListItem组件的子组件添加focusable(true)
即可。例如首页最顶部是一个搜索框,搜索框的ListItem的子组件为Row容器组件,由于Row组件不支持焦点事件,可以给Row容器下的子组件Image或Text任一组件添加focusable
属性设置为true
,便可以通过键盘的TAB键或方向键进行获焦了。可获焦的组件可以触发按键事件进行操作,通过给组件添加onKeyEvent事件,在事件触发时执行相应的函数代码,例如这里判断当键盘按了回车键时就跳转页面。
List({ space: this.listSpaces }) {
// search
ListItem() {
Row() {
Image($r("app.media.ic_search"))
...
.focusable(true)
.onFocus(() => {
this.searchFocused = true
})
.onBlur(() => {
this.searchFocused = false
})
.onKeyEvent((event: KeyEvent) => {
if (event.keyCode === KEYCODE_ENTER || event.keyCode === KEYCODE_NUMPAD_ENTER) {
router.push({
url: 'pages/searchPage'
})
}
});
Text($r("app.string.searchHint"))
...
}
...
ListItem() {
List() {
ListItem() {
// WLAN
SettingItemComponent({
...
})
}
ListItem() {
// blueTooth
SettingItemComponent({
...
})
}
ListItem() {
// mobileData
SettingItemComponent({
...
})
}
...
}
...
}
...
}
同理,为WLAN、蓝牙等ListItem添加焦点事件只需要为自定义组件SettingItemComponent
下支持焦点控制的组件添加对应的属性及事件即可
@Component
export struct SettingItemComponent {
...
@State isFocused: boolean = false;
build() {
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
Row() {
Image(this.settingIcon)
...
.focusable(true)
.onFocus(() => {
this.isFocused = true
})
.onBlur(() => {
this.isFocused = false
})
.onKeyEvent((event: KeyEvent) => {
if (event.keyCode === 2054 || event.keyCode === 2119) {
SettingListModel.onSettingItemClick(this.targetPage);
}
})
Text(this.settingTitle)
...
}
...
Row() {
Text(this.settingEndText)
...
Image('/res/image/ic_settings_arrow.svg')
...
}
...
}
.linearGradient(this.isTouched || this.isFocused ? {
angle: 90,
direction: GradientDirection.Right,
colors: [[$r("app.color.DCEAF9"), 0.0], [$r("app.color.FAFAFA"), 1.0]]
} : {
angle: 90,
direction: GradientDirection.Right,
colors: [[$r("sys.color.ohos_id_color_foreground_contrary"), 1], [$r("sys.color.ohos_id_color_foreground_contrary"), 1]]
})
...
}
}
参考资料
结语
目前焦点事件支持的组件较少,同时存在一些问题,例如:
1、从当前应用进入到另一个应用,再退回当前应用时焦点消失,需要等一会才会出现
2、在当前页面打开一个弹窗,正常逻辑应该是焦点跑到弹窗上,但是实际情况却是在弹窗下的页面也能走焦
3、页面不能跟随焦点的移动方向进行滑动,当焦点不在当前页面时,页面仍保持不动
4、应用首次启动第一个组件便是获焦态,正常逻辑应为操控键盘或者遥控器才出现焦点
5、Button自带的获焦态样式只有tab键可以触发,方向键不可以,然而遥控器是没有tab键的
【小源笔记】为笔者开发过程中的一些经验分享,旨在解决官方文档过于晦涩难懂或者示例代码不够详细的问题,同时方便笔者日后回顾以及其他开发者更快上手,欢迎评论留言~
往期推荐: