Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView: Disable scrolling caused by change in focus

TL;DR I have a RecyclerView of EditTexts. When the user is focused on EditText #1 and taps on EditText #2, I want EditText #2 to get focus but I don't want the ReyclerView to scroll. How can I achieve this?


I'm trying to work with a RecyclerView populated with a bunch of EditTexts. When I'm focused on one EditText and I click on another, the RecyclerView scrolls so that the second is at the top of the screen. I want to disable this auto-scrolling from the RecyclerView, but I still want the user to be able to scroll, and I still want the second EditText to be focused on so the user can start typing. How can I achieve this?

I've already tried the following solutions:

  • https://stackoverflow.com/a/8101614/4077294, but with a RecyclerView.OnItemTouchListener. I called recyclerView.requestFocusFromTouch in onInterceptTouchEvent.

    • Behavior: Scrolled to the top of the tapped EditText all the time.
  • Clearing the focus from any EditText whenever it was focused on, via

    editText.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, bool hasFocus) {
            if (hasFocus) {
                v.clearFocus();
            }
        }
    });
    
    • Behavior: The keyboard never showed up, and the RecyclerView still scrolled to the top.

Disabling scrolling altogether as in this question is not acceptable because I still want the user to be able to scroll.

like image 760
James Ko Avatar asked Jul 09 '17 04:07

James Ko


People also ask

Why won't my recyclerview scroll?

In particular, if your RecyclerView is in a ScrollView but does not fill the screen, the ScrollView will not scroll (content fits in screen), and you will get the scroll UI in your RecyclerView (end of list effect when trying to scroll for example) even though it will not scroll when it gets bigger. Extending the LayoutManager really does the job.

Why does my view disappear when I scroll down or back?

After that when I scroll down or go up the view back to its normal position like the changes that I made it’s gone from view. It is because RecyclerView recycles every view which is not visible to the user. So, when the user scrolls back it recycles the previous view which is in normal form.

How to disable scroll/swipe events in recyclerview?

Instead of returning true, and therefore disabling all sorts of touch events, just return e.getAction () == MotionEvent.ACTION_MOVE; instead of return true; so only scroll/swipe events get cancelled. As setLayoutFrozen is deprecated, You can disable scrolling by freezing your RecyclerView by using suppressLayout.

How to change the background color of itemview when user scrolls bottom?

So, when it is called we stored a flag value in our BokkModel class. Now when the user scrolls bottom or comes back to the previous position the view never changes. You can also add ClickListener on itemView when the user taps on the row you can change the background color and store in the model.


2 Answers

I ended up with this solution from @pskink:

recylerView.setLayoutManager(new LinearLayoutManager(this) {
    @Override
    public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate) {
        return false;
    }
});

It seems to work perfectly, but @pskink has mentioned that this could have problems when using arrow keys. He's posted another solution here: https://pastebin.com/8JLSMkF7. If you have problems with the above solution, you may try the alternative solution at the link. For now, I'm sticking with the one I just posted here.

UPDATE

Since support-library v25.3.0 you should also override another requestChildRectangleOnScreen method in LayoutManager:

@Override
public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate, boolean focusedChildVisible) {
    return false;
}
like image 98
James Ko Avatar answered Oct 19 '22 18:10

James Ko


RecyclerView will scroll to focused item. Try recyclerView.setFocusable(false). This worked for me.

like image 34
user3890624 Avatar answered Oct 19 '22 17:10

user3890624