EditText 失去对 RecyclerView 中 Scroll 的关注

EditText loses focus on Scroll in RecyclerView

我有一个 RecyclerView,它的列表项是 EditText。当我滚动 RecyclerView 时,当项目离开屏幕时 EditText 失去焦点。因此,当 EditText 滚动返回屏幕时,焦点不会停留在 EditText 上。

我希望焦点保持在同一项目上。为此,我还尝试将 position 的项目存储在焦点上并将焦点重新分配到 onBindViewHolder 中。但这会减慢滚动速度。

我也用 ListView 尝试过,但还有另一种 focus 相关的问题。焦点跳到那里。

已在 SO 上搜索此地段并在 Google 上搜索了很多。但总能找到像 android:focusableInTouchMode="true"android:descendantFocusability="afterDescendants" 这样的答案,但这些答案不起作用。

非常感谢任何帮助。

RecyclerView 的全部意义在于重用视图,这样 phone 就不必一次将所有行保存在内存中,也不必不断销毁和创建视图。当您的 EditText 离开屏幕时,phone 获取该视图,重置其内容并将其移动到传入视图堆栈的底部。

这意味着一旦您的 EditText 离开屏幕,它就不再存在。它无法保持焦点,因为它已从布局中移除。

解决此问题的唯一方法就是您提到的方法,即存储位置、检查该位置何时出现在屏幕上以及手动恢复焦点。

正如 所写,我们应该存储位置并在滚动后屏幕上出现项目时恢复它。

问题是我们不知道该项目何时出现和消失。当我们有多个ViewHolder的时候,甚至连onBindViewHolder都不能再调用了。在这种情况下,我们应该使用 onViewAttachedToWindowonViewDetachedFromWindow 来了解项目何时出现和消失在屏幕上。

private var focusPosition: Int = -1

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    super.onBindViewHolder(holder, position)

    // Choose right ViewHolder and set focus event.
    holder.edit_text.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
        focusPosition = position
    }
}

override fun onViewAttachedToWindow(holder: ViewHolder) {
    super.onViewAttachedToWindow(holder)
    // Your condition, for instance, compare stored position or item id, or text value.
    if (holder.adapterPosition == focusPosition && holder is SomeViewHolder) {
        holder.edit_text.requestFocus()
    }
}

//override fun onViewDetachedFromWindow(holder: UinBillViewHolder) { //
//    super.onViewDetachedFromWindow(holder)
//}

尝试使用下一个:

LinearSnapHelper snapHelper  = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);

它在垂直方向使用 GridLayoutManager 时帮助了我。

此选项会自行稍微滚动列表,以便在滚动时,RecyclerView 中下一个项目的边缘变得可见,因此焦点不会丢失。

但如果您需要滚动得太快(如果该列没有时间加载,您需要进一步滚动),这将无济于事。

我在这里找到了答案Scrolling recyclerview from the middle item