新方法:
用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);