RecyclerView 中滚动时 EditText 失去焦点

9
我有一个RecyclerView,其中的列表项是EditText。当我滚动RecyclerView时,如果项目离开屏幕,EditText会失去焦点。所以,当EditText再次出现在滚动中时,焦点不会停留在EditText上。
我希望焦点仍然保持在相同的项目上。为此,我尝试在onBindViewHolder中存储聚焦项的位置并重新分配焦点。但这会减慢滚动速度。
我还尝试了使用ListView,但也存在另一种与焦点相关的问题。
我在SO和Google上搜索了很多资料,但总是找到像“android:focusableInTouchMode="true"”和“android:descendantFocusability="afterDescendants"”之类的答案,但都无效。
非常感谢您的任何帮助。
3个回答

9
< p >一个RecyclerView的主要作用就是重复利用视图,以便手机不必一次性将所有行保存在内存中,并且不必不断地销毁和创建视图。当您的EditText离开屏幕时,手机会获取该视图,重置其内容并将其移动到传入视图堆栈的底部。

RecyclerView diagram

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

唯一的解决方法是存储位置,检查何时该位置出现在屏幕上,并手动恢复焦点。


当有2个项目(2个不同的视图持有者)时,RecyclerView可以在滚动时清除焦点,即使没有调用onBindViewHolder,因此我们不能再次设置焦点。在这种情况下,我们应该使用onViewAttachedToWindow - CoolMind

1

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

问题是我们不知道项目何时出现和消失。当我们有几个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)
//}

0

尝试使用下一个:

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

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

这个选项会自动滚动列表一点,这样当滚动时,RecyclerView中下一个项目的边缘就会可见,这样焦点不会丢失。

但是如果需要快速滚动(如果列没有加载完,需要继续滚动),这将无济于事。

我在这里找到了答案 从中间项滚动recyclerview


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接