Android TV开发之焦点控制

扯淡
在Android TV开发中,最常处理的事情就是焦点的控制了,就像手机APP开发中的触摸事件的处理一样。但两者的处理有很大的区别,手机上是用手指触摸,可以随意点击任意的位置。而TV主要是通过遥控器上下左右移动焦点来操作,下一个焦点在哪,并不是随意的,都是由系统默认的规则或我们的设置来控制的。系统默认的规则是,将焦点交给在该方向上,离当前焦点view最近的,且是可获得焦点的View。
下面是我们常用到的焦点相关方法:

焦点监听

	//全局焦点监听
    view.viewTreeObserver.addOnGlobalFocusChangeListener(object :ViewTreeObserver.OnGlobalFocusChangeListener{
        override fun onGlobalFocusChanged(oldFocus: View?, newFocus: View?) {
            //TODO
        }
    })
    
    //view的焦点监听
    view.setOnFocusChangeListener(object :View.OnFocusChangeListener{
        override fun onFocusChange(v: View?, hasFocus: Boolean) {
            //TODO
        }
    })    

判断view和它的子view是否有焦点

	view.hasFocus()

设置view可获得焦点

	isFocusableInTouchMode = true

如果是button,或者设置了点击事件的view,则默认就是可获得焦点的,不需要设置。

默认获取焦点

	android:focusedByDefault="true"

请求焦点

	view.requestFocus()

控制上下左右的焦点

	view.nextFocusUpId = R.id.view1
	view.nextFocusDownId = R.id.view2
	view.nextFocusLeftId = R.id.view3
	view.nextFocusRightId = R.id.view4

也可以在布局中指定。若要控制焦点不能出当前View,可以指定上下左右的id全部为自己。

监听方向键进行操作

    view.setOnKeyListener(object : View.OnKeyListener {
        override fun onKey(v: View, keyCode: Int, event: KeyEvent): Boolean {
            when(keyCode){
                KeyEvent.KEYCODE_DPAD_UP->{//TODO}
                KeyEvent.KEYCODE_DPAD_DOWN->{//TODO}
                KeyEvent.KEYCODE_DPAD_LEFT->{//TODO}
                KeyEvent.KEYCODE_DPAD_RIGHT->{//TODO}
            }
            return false
        }
    })

若事件处理完成,应该返回true。

焦点恢复
Android TV应用中,常见的设计都是上面有一个tab栏,显示不同的内容标签。当焦点切换到tab栏下方的内容展示区域中,再切换回tab栏时,焦点恢复到上次选中的标签上。如果tab栏使用的是leanback库中的 VerticalGridView 或者 HorizontalGridView ,那焦点会自动恢复,不需要我们额外处理。但如果使用的普通的ViewGroup,那我们就需要自己处理了。

class TabContainerView : FrameLayout {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun addFocusables(views: ArrayList<View>?, direction: Int, focusableMode: Int) {
        if (!hasFocus()) {
            for (i in 0 until childCount) {
                val child = getChildAt(i)
                if (child.visibility == View.VISIBLE
                    && child.getTag(R.id.tab_focus_flag) as? Boolean == true
                ) {
                    views?.add(child)
                    return
                }
            }
        }
        super.addFocusables(views, direction, focusableMode)
    }
}

自定义一个ViewGroup继承FrameLayout,并重写 addFocusables 方法。系统在处理焦点时,会调用ViewGroup的 findFocus 查找下一个焦点view,findFocus 里面 会调用 addFocusables 方法将所有可以获取焦点的View收集起来,然后在根据他们的位置,决定将焦点给谁。addFocusables 直接影响findFocus 的结果,我们可以重写该方法,将要恢复的标签添加到views中,其他的就不添加。这里通过子view是否有TAG来找到要恢复焦点的view,TAG在外部设置,这样就只让这个view获取到焦点,从而恢复tab栏的焦点。

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android TV远程控制可以通过安装一个名为TvRemoteIME的应用程序来实现。这个应用程序通过一个Http服务器与待控制的设备上的TvRemoteIME输入法程序进行通信,并执行具体的操作逻辑。这种方式非常方便,只需要在待操作的设备上安装一个App,然后通过Http服务,无论是在Android、iOS还是Web端,都可以对其进行控制。\[1\] 如果您是非开发人员,可以按照以下步骤进行远程安装apk: 1. 在您的电视应用市场下载一个沙发管家或者当贝市场,这里以沙发管家为例。 2. 下载完成后打开沙发管家,使用遥控器移动到工具箱栏目下,找到远程推送选项。\[2\] 最近,TvRemoteIME已经更新,现在可以不依赖输入法就可以使用,但是如果不设置输入法,无法使用控制相关的功能。这对整个App的功能来说是致命的,后期还需要考虑如何保持活跃和解决控制问题。\[3\] #### 引用[.reference_title] - *1* *3* [远程控制你的智能电视,按键|输入|安装App等都已实现,已开源!](https://blog.csdn.net/weixin_33755554/article/details/87958060)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [AndroidTV开发12——大屏TV电视及盒子Apk远程安装说明文档](https://blog.csdn.net/u012556114/article/details/126201288)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值