RecyclerView: Disable scrolling caused by change i

2020-06-14 09:19发布

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.

2条回答
虎瘦雄心在
2楼-- · 2020-06-14 09:42

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

查看更多
女痞
3楼-- · 2020-06-14 09:53

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;
}
查看更多
登录 后发表回答