Android TV 开发 RecycleView重新获得焦点并回到原来的item位置让item获取焦点

新方法:

用HorizontalGridView和VerticalGridView代替RecyclerView,使用方法与RecyclerView基本一致,只是不需要设置LayoutManager。

另外,如果想要焦点跃出边界,需要xml设置(手打):

app:focusOutFront="true"

(弃~)

旧——

在看了很多资料,有些还需要自定义recycleview来实现,过于麻烦,于是自己实现了一个比较简单的方法。

需要一个View 用来保存最后获取焦点的item: 

private View lastView = null; 

如果该页面不是一直驻留,可能会退出或销毁,建议—— 

@Override
    public void onDestroyView() {
        super.onDestroyView();
        lastView = null;
    }

 RecycleView添加监听:

wifiBinding.recycleView.setOnFocusChangeListener((v, hasFocus) -> {
    Log.d(TAG, "onFocusChange: " + lastView);
    if (hasFocus) {
        //重新获得焦点后回到保存的位置
        if (lastView != null) {
            lastView.setSelected(true);
            lastView.requestFocus();
        }
    }
});

XML添加以下两行:

android:focusable="true"

android:descendantFocusability="beforeDescendants"

<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycleView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_marginStart="50dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="250dp"
            android:layout_marginBottom="20dp"
            android:nextFocusLeft="@id/refresh"
            android:nextFocusUp="@id/backpress"
            android:padding="10dp"
            android:focusable="true"
            android:descendantFocusability="beforeDescendants"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/connected" />

最后在RecycleView.ViewHolder中进行更新lastView事件—— 

private class ViewHolder extends RecyclerView.ViewHolder {
    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        itemView.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus) {
        //时刻更新最近获得焦点的item,并保存
                if (lastView != null) {
                    lastView = v;
                }
            }
        });
    }
    @SuppressLint("SetTextI18n")
    public void bind(Wifi item, int position) {        
        //此处作用只是在初始化时获得第一个position的View
        if (lastView == null) {
            if (position == 0) {
                lastView = itemView;
            }
        }
    }
}

另外一些小问题:

刷新recycleview 数据后,会失去焦点,处理方法如下:

(该方法无法回到原先item,本人做的wifi设置,recycleview获取的是wifi列表,之前选中的item可能在刷新数据后就消失了,故使得刷新后的焦点回到列表最上方(初始位置)。

adapter.setHasStableIds(true);

在adapter中重写方法:

@Override
public long getItemId(int position) {
    return position;
}

在刷新数据前使:

lastView = null;
layoutManager.scrollToPosition(0);

猜你喜欢

转载自blog.csdn.net/weixin_44917215/article/details/126389974