【问题标题】:Loop focus in RecylerView for TvRecyclerView for Tv 中的循环焦点
【发布时间】:2019-11-07 13:09:43
【问题描述】:

根据https://developer.android.com/training/tv/start/navigation

您应该将导航顺序设置为循环,以便最后一个 控件将焦点引导回第一个。

我已尝试为 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 }
    }
}

所以在布局更改时,我让第一个视图有nextFocusUpId 引用最后一个视图,最后一个视图nextFocusDownId 引用第一个视图。但它只适用于所有视图都实际布局在屏幕上的情况,这在一般情况下显然不是真的。 RecyclerView 实际上是回收视图,所以最后一个视图和第一个视图可能不会同时出现在屏幕上

如何在leanback模式下实现rv的焦点循环? 我尝试使用来自leanback 库的androidx.leanback.widget.VerticalGridView,但它也没有必需的行为。

默认情况下,从 rv 焦点的第一个可聚焦项目向上按会跳转到 rv 之外的其他可聚焦视图,这不太合适

【问题讨论】:

    标签: android android-tv leanback


    【解决方案1】:

    默认情况下,从 rv 焦点的第一个可聚焦项目向上按会跳转到 rv 之外的其他可聚焦视图,这不太合适

    首先,至于用户体验,如果您的列表上方有视图,那么如果您想要滚动到最后一个项目或转到上面的视图,那么按下确实会成为问题。

    话虽如此,如果您在列表上方有一个也应该获得焦点的视图,我建议您在这种情况下仅从底部提供循环选项。

    一般来说,我建议您检查 VerticalGridView/Horizo​​ntalGridView 以在后靠应用程序中添加行和列表。

    在示例中,我将其调整为使用 RecyclerView 来解决您的问题。

    为此,您必须捕获按钮事件,检查它是否是最后一项,如果是,则请求焦点到第一项。

    @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;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-11
      • 2017-01-07
      • 2021-01-02
      • 2018-08-27
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 2011-10-18
      • 2022-10-15
      相关资源
      最近更新 更多