How to disable RecyclerView scrolling?

2019-01-03 01:48发布

I cannot disable scrolling in the RecyclerView. I tried calling rv.setEnabled(false) but I can still scroll.

How can I disable scrolling?

24条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-01-03 02:36

There is a more straightforward way to disable scrolling, using just standard functionality. RecyclerView has the method called addOnScrollListener(OnScrollListener listener), and using just this you can stop it from scrolling, just so:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (viewModel.isItemSelected) {
            recyclerView.stopScroll();
        }
    }
});

Use case: Let's say that you want to disable scrolling when you click on one of the items within RecyclerView so you could perform some actions with it, without being distracted by accidentally scrolling to another item, and when you are done with it, just click on the item again to enable scrolling. For that, you would want to attach OnClickListener to every item within RecyclerView, so when you click on an item, it would toggle isItemSelected from false to true. This way when you try to scroll, RecyclerView will automatically call method onScrollStateChanged and since isItemSelected set to true, it will stop immediately, before RecyclerView got the chance, well... to scroll.

Note: for better usability, try to use GestureListener instead of OnClickListener to prevent accidental clicks.

查看更多
趁早两清
3楼-- · 2019-01-03 02:37

This a bit hackish workaround but it works; you can enable/disable scrolling in the RecyclerView.

This is an empty RecyclerView.OnItemTouchListener stealing every touch event thus disabling the target RecyclerView.

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return true;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

Using it:

RecyclerView rv = ...
RecyclerView.OnItemTouchListener disabler = new RecyclerViewDisabler();

rv.addOnItemTouchListener(disabler);        // disables scolling
// do stuff while scrolling is disabled
rv.removeOnItemTouchListener(disabler);     // scrolling is enabled again 
查看更多
做个烂人
4楼-- · 2019-01-03 02:37

Another alternative is setLayoutFrozen, but it comes with a bunch of other side effects.

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setLayoutFrozen(boolean)

查看更多
太酷不给撩
5楼-- · 2019-01-03 02:37

You can disable scrolling by freezing your RecyclerView.

To freeze: recyclerView.setLayoutFrozen(true)

To unfreeze: recyclerView.setLayoutFrozen(false)

查看更多
小情绪 Triste *
6楼-- · 2019-01-03 02:39

I know this already has an accepted answer, but the solution doesn't take into account a use-case that I came across.

I specifically needed a header item that was still clickable, yet disabled the scrolling mechanism of the RecyclerView. This can be accomplished with the following code:

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
                    @Override
                    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                        return e.getAction() == MotionEvent.ACTION_MOVE;
                    }

                    @Override
                    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

                    }

                    @Override
                    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

                    }
                });
查看更多
唯我独甜
7楼-- · 2019-01-03 02:40

The real answer is

recyclerView.setNestedScrollingEnabled(false);

More info in documentation

查看更多
登录 后发表回答