Android 电视RecylerView中的循环焦点
据 您应该将导航顺序设置为循环,以便 控件将焦点引导回第一个焦点 我已尝试为Android 电视RecylerView中的循环焦点,android,android-tv,leanback,Android,Android Tv,Leanback,据 您应该将导航顺序设置为循环,以便 控件将焦点引导回第一个焦点 我已尝试为RecyclerView项目实施此类行为: fun RecyclerView.loopFocusVertically() { viewTreeObserver.addOnGlobalLayoutListener { val children = getAllChildren() val firstFocusableItem = children.firstOrNull { it.i
RecyclerView
项目实施此类行为:
fun RecyclerView.loopFocusVertically() {
viewTreeObserver.addOnGlobalLayoutListener {
val children = getAllChildren()
val firstFocusableItem = children.firstOrNull { it.isFocusable }
val lastFocusableItem = children.lastOrNull { it.isFocusable }
firstFocusableItem?.let { it.nextFocusUpId = lastFocusableItem?.id ?: it.id }
lastFocusableItem?.let { it.nextFocusDownId = firstFocusableItem?.id ?: it.id }
}
}
因此,在布局更改时,我使第一个视图对最后一个视图进行了nextfocuspid
引用,而最后一个视图对第一个视图进行了nextFocusDownId
引用。但它只适用于所有视图都实际布置在屏幕上的情况,这在一般情况下显然是不正确的RecyclerView
实际上会回收视图,所以最后一个视图和第一个视图可能不会同时出现在屏幕上
如何在leanback模式下为rv实施聚焦循环?
我曾尝试使用leanback库中的androidx.leanback.widget.VerticalGridView
,但它也没有必需的行为
默认情况下,从rv焦点的第一个可聚焦项向上按时,会跳转到rv外部的其他可聚焦视图,这不太合适
默认情况下,从rv焦点的第一个可聚焦项向上按时,会跳转到rv外部的其他可聚焦视图,这不太合适
首先,对于用户体验,如果您的列表上方有视图,那么确实会有问题,因此如果您想滚动到最后一项或转到上面的视图,则按向上键确实会有问题
话虽如此,我建议您在这种情况下,如果列表上方有一个视图也应该获得焦点,那么只从底部给出循环选项
一般来说,我建议您检查VerticalGridView/HorizontalGridView,以便在一个精益应用程序中添加行和列表
在本例中,我对其进行了调整,以使用RecyclerView来回答您的问题
为此,您必须捕获button事件,检查它是否是最后一项,如果是,则请求聚焦到第一项
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
if (onDownClick(event)) {
return true;
}
}
}
return super.dispatchKeyEvent(ev);
}
public boolean onDownClick(KeyEvent event) {
int currentIndex = 0;
if (mAdapter != null) {
currentIndex = mAdapter.indexOf(mCurrentItem);
}
if (currentIndex == mAdapter.size() - 1) {
mListRecycler.scrollToPosition(0);
if (mListRecycler.findViewHolderForAdapterPosition(0) != null) {
mListRecycler.findViewHolderForAdapterPosition(0).itemView.requestFocus();
}
return true;
}
return false;
}