EditText loses focus on Scroll in RecyclerView

Viewed 3406

I have a RecyclerView which have EditText as its list items. When i scroll the RecyclerView, the EditText loses focus when the item goes off screen. So the focus does not remain on the EditText when it comes back on the screen on scroll.

I want the focus to remain on the same item. For that i also tried storing position of the item on focus and reassigning the focus in onBindViewHolder. But that slow downs the scrolling.

I also tried this with ListView but there is another kind of focus related problem. Focus jumps there.

Have searched for this lot on SO and Googled a lot. but always found answers like android:focusableInTouchMode="true" and android:descendantFocusability="afterDescendants" which does not work.

Any help would be highly appreciated.

3 Answers

As Elan Hamburger wrote, we should store the position and restore it when an item appears on screen after scrolling.

A problem is we don't know when the item appears and disappears. When we have several ViewHolders, onBindViewHolder can even not be invoked again. In this case we should use onViewAttachedToWindow and onViewDetachedFromWindow to learn when the item appears and disappears on screen.

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)
//}

Try use the next:

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

It helped me when using GridLayoutManager with Vertical orientation.

This option scrolls the list a little on its own so that when scrolling, the edge of the next items in the RecyclerView becomes is visible, so the focus is not lost.

But this does not help if you need to scroll too quickly (if the column did not have time to load, and you need to scroll further).

I found the answer here Scrolling recyclerview from the middle item

Related