一、焦点获取
首先,TV端的开发和我们手机端开发最大的区别就在于TV端存在焦点的概念。
如下图:
可想而知,手机端我们直接通过点击\长按某个区域处理响应事件处,但是TV端只能通过遥控器的上下左右来操控焦点,从而选中特定的区域处理相应事件。
在TV开发中没有以前我手机端的dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent 事件来分发,而需要使用dispatchKeyEvent、onKeyDown、onKeyLisenter 等事件来分发处理焦点事件传递。
然而TV端焦点没有什么好办法可以全局控制焦点,需要我们自己来想办法规定焦点走向,一旦焦点没有处理好就会造成焦点丢失。
android提供了一些焦点相关的属性,在现有的框架层下通过设置View的属性来获得焦点:
- android:focusable:设置一个控件能否获得焦点
- android:nextFocusDown:(当按下键时)下一个获得焦点的控件
- android:nextFocusDown:(当按下键时)下一个获得焦点的控件
- android:nextFocusLeft:(当按下键时)下一个获得焦点的控件
- android:nextFocusRight:(当按下键时)下一个获得焦点的控 **注意:**如果按下某个方向键时,想让焦点停留在自身,可以使用
android:nextFocusRight:"@null"
或者android:nextFocusRight:"@id/自身id"
栗子:如下图:
我们想要实现firstView(按右键)-->secondView(按下键)-->threadView(按上键)-->firstView
步骤:
- 第一步:让这firstView、secondView、threadView获取焦点
- 第二步:控制这三个View的移动轨迹
- 注意:fourthView没有涉及到焦点,我们不用做任何处理
示例:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/firstView"
android:layout_width="40dp"
android:layout_height="40dp"
android:focusable="true"
android:nextFocusDown="@null"
android:nextFocusLeft="@null"
android:nextFocusRight="@id/secondView"
android:nextFocusUp="@null" />
<View
android:id="@+id/secondView"
android:layout_width="60dp"
android:layout_height="60dp"
android:focusable="true"
android:nextFocusDown="@id/threadView"
android:nextFocusLeft="@null"
android:nextFocusRight="@null"
android:nextFocusUp="@null" />
<View
android:id="@+id/threadView"
android:layout_width="30dp"
android:layout_height="30dp"
android:focusable="true"
android:nextFocusDown="@null"
android:nextFocusLeft="@null"
android:nextFocusRight="@null"
android:nextFocusUp="@id/firstView" />
<View
android:id="@+id/fourthView"
android:layout_width="100dp"
android:layout_height="40dp" />
</android.support.constraint.ConstraintLayout>
复制代码
也可以在代码中设置:
threadView.setNextFocusLeftId(R.id.firstView);
secondView.setNextFocusDownId(R.id.threadView);
复制代码
注意:
- 开发过程中我们有时需要布局初始化就有一个View是聚焦状态,那么可以使用
requestFocus()
来请求焦点。
那么此时问题来了,我们肉眼如何知道焦点在哪一个View上?
此时就需要我们对焦点选中的View进行样式改变,有一下两种方法:
二、聚焦时View样式
方法一:
android:background:设置背景的drawable
android:textColor:设置字体颜色
复制代码
对应的xml文件: drawable的xml文件,焦点选中时显示为keyboard_add,否则显示为keyboard_add_sel
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/keyboard_add_sel" android:state_focused="true" />
<item android:drawable="@drawable/keyboard_add" android:state_focused="false"/>
</selector>
复制代码
color的xml文件,焦点选中时显示#4194ff(蓝色),否则显示#29ffffff(灰色)
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item androi