AndroidTV焦点问题总结
焦点
1.确定当前焦点位置
在一些复杂的View中,频繁按遥控器,焦点丢失,可以通过如下方法获取全局焦点所在的View
ViewTreeObserver viewTreeObserver = getWindow().getDecorView().getViewTreeObserver();
viewTreeObserver.addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
Log.d(TAG, "oldFocus========" + oldFocus + "newFocus============" + newFocus);
}
});
2.子view焦点跟随父View变化
父View是一个ViewGroup,有焦点时背景变化,子View是一个TextView有焦点时字体颜色变化
android:duplicateParentState="true"
3.设置下一个获取焦点的View
android:nextFocusDown="@id/view1"
android:nextFocusUp="@id/view2"
android:nextFocusLeft="@id/view3"
android:nextFocusRight="@id/view4"
4.设置父View和子View哪个获取焦点
使用descendantFocusability属性
- beforeDescendants :viewGroup会优先其子类控件而获取到焦点
- afterDescendants :viewGroup只有当其子类控件不需要获取焦点时才获取焦点
- blocksDescendants :viewGroup会覆盖子类控件而直接获得焦点
5.常用的按键值
KEYCODE_BACK 4返回
KEYCODE_DPAD_DOWN 20
KEYCODE_DPAD_UP 19
KEYCODE_DPAD_LEFT 21
KEYCODE_DPAD_RIGHT 22
KEYCODE_ENTER = 66;
KEYCODE_MEDIA_REWIND 快退
KEYCODE_MEDIA_FAST_FORWARD 快进
KEYCODE_VOLUME_DOWN = 25;
KEYCODE_VOLUME_MUTE = 164;
KEYCODE_VOLUME_UP = 24;
7.控制RecycleView焦点跳转逻辑
例 item最后一行未满,倒数第二行DOWN需要跳转下一行
参考文章跳转逻辑逻辑修改
8.其他View焦点跳转到RecyclerView
- RecyclerView第一次获得焦点,默认选中第一项
- RecyclerView重新获得焦点后,选中上次的item
Android系统的焦点跳转规则是就近跳转,以上两点可能无法满足。使用HorizontalGridView或者VerticalGridView则可以解决以上两点问题。
9.ViewGroup的某个子View获取焦点
handler.postDelayed(() -> {
View child = videoPlayerHolder.ctrlInfoList.getChildAt(0);
View list = child == null ? null : ((LinearLayout) child).getChildAt(1);
View item = list == null ? null : ((HorizontalGridView) list).getChildAt(currentIndex);
if (child == null || list == null) {
videoPlayerHolder.ctrlInfoList.requestFocus();
} else {
if (item == null) {
list.requestFocus();
} else {
item.requestFocus();
}
}
}, 50);