更新记录
1.0.1(2025-06-16)
第一版发布
1.0.0(2025-06-16)
第一版发布
平台兼容性
uni-app x
Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
---|---|---|---|---|---|
- | - | 5.0 | - | - | - |
xf-tv-view
xf-tv-view 是一个专为 Android TV 平台设计的 Vue 组件,主要用于处理焦点管理和按键事件。该组件封装了 Android TV 设备的焦点逻辑和按键响应机制,方便在 UniAppX 中开发 TV 端应用时使用。
也可以开发其他需要按键控制支持的应用
该插件只支持安卓端uniapp-X,本插件以经过完整的影视TV APP开发及使用过,可放心使用,可完整实现遥控控制、快进快退等等逻辑(通过keyCallback回调实现逻辑)。
组件提供了焦点状态管理、焦点样式切换、按键事件回调等功能,支持自定义焦点样式、默认焦点设置以及按键事件的自定义处理。
使用本组件请尽量在子组件中封装及实现按钮等样式,不要在子组件中使用button等组件,这些组件本身也含有聚焦事件,会有冲突。如果非要使用,请设置button的id,并在xf-tv-view上设置focusId后自行尝试,作者并未试验过。
属性
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
focusId | String | null | 关联的焦点元素 ID,用于获取对应的 Android View |
focusClass | String | "" | 获得焦点时的样式类名 |
unFocusClass | String | "" | 失去焦点时的样式类名 |
defaultFocus | Boolean | false | 是否默认获取焦点 |
keyCallback | Function | null | 按键事件回调函数,用于处理自定义按键逻辑 |
disabledEnterKeyDown | Boolean | false | 是否禁用 Enter 键按下事件 |
focusable | Boolean | true | 是否可聚焦 |
focusId说明
大多数情况下不需要设置focusId,在某些特殊情况下,比如在xf-tv-view下嵌入了video组件,那么你就需要给video组件设置设置id,并在xf-tv-view的focusId填入该id,这样在视频全屏时才能正确的获取遥控器事件,然后通过keyCallback回调处理快进快退播放等功能实现
keyCallback
多数情况下不需要使用到该回调,系统原生会处理上下左右的聚焦管理,你可以通过onEnterKeyDown事件直接处理对应功能。 用到该回调的情况一是上面提到的视频全屏时的复杂功能开发。二是系统的聚焦管理需要优化的情况下,特殊情况系统的聚焦管理会跳到不是很理想的位置,你就需要手动处理
组件事件
事件名 | 触发条件 | 回调参数 | 描述 |
---|---|---|---|
focusChange | 焦点状态改变时 | hasFocus: Boolean | 传递新的焦点状态 |
onTvFocus | 获得焦点时 | - | 焦点获取事件 |
onTvBlur | 失去焦点时 | - | 焦点丢失事件 |
onKeyDown | 按键按下时 | keyCode: Number | 传递按下的按键码 |
onEnterKeyDown | Enter 或方向键中心按下时 | - | Enter 键按下事件 |
组件方法
requestFocus():使组件获取焦点 调用示例:(this.$refs["xxxx"] as XfTvViewComponentPublicInstance).requestFocus()
setFocusable(enable : boolean) 设置组件是否可以对焦
示例代码
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<!-- <view>
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
</view> -->
<view>简单使用,组件默认提供了确定键的事件</view>
<view style="display: flex;flex-direction: row;flex-wrap: wrap;">
<!-- 简单使用 -->
<xf-tv-view v-for="(item,index) in exampleData" style="padding: 10px;width: 230rpx;"
focus-class="border-red" :un-focus-class="index==3?'border-green':''" :default-focus="index==5"
:focusable="index!=6" @onEnterKeyDown="handlerTvEnter(item) " :disabledEnterKeyDown="index==7">
<text>{{item}}</text>
</xf-tv-view>
</view>
<view style=""></view>
<view style="margin-top: 20px;">完整事件拦截,拦截元素的所有按键事件自行处理</view>
<xf-tv-view style="padding: 10px;width: 230rpx;" focus-class="border-red"
un-focus-class="border-green" :keyCallback="keyEventCallBack">
<view>
<image class="logo" src="/static/logo.png"></image>
<text>完整事件拦截示例</text>
</view>
</xf-tv-view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
import KeyEvent from 'android.view.KeyEvent';
export default {
data() {
return {
title: 'Hello',
exampleData: [
"示例1",
"示例2",
"示例3",
"示例4",
"示例5",
"示例6",
"示例7",
"示例8",
"示例9",
]
}
},
onLoad() {
},
methods: {
handlerTvEnter(item : string) {
uni.showToast({
title: item
})
},
keyEventCallBack(event : KeyEvent) {
//KeyEvent事件码请参阅https://developer.android.google.cn/reference/android/view/KeyEvent
//调用组件的方示例
//(this.$refs["xxxx"] as XfTvViewComponentPublicInstance).requestFocus()
console.log(event);
if (KeyEvent.ACTION_DOWN == event.getAction()) { //当为按下动作时自行
if (KeyEvent.KEYCODE_ENTER == event.getKeyCode() || KeyEvent.KEYCODE_DPAD_CENTER == event.getKeyCode()) {
uni.showToast({
title: "按键按下了"
})
}
}
//该方法返回true则会拦截系统默认的事件处理器
//例如 系统默认上下左右导航键是会移动聚焦对象的 可自行设置为true体验
return false;
},
}
}
</script>
<style>
.border-red {
border: 5px solid red;
}
.border-green {
border: 5px solid green;
}
</style>