How to disable RecyclerView scrolling?
Asked Answered
M

34

321

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

How can I disable scrolling?

Meteoritics answered 29/5, 2015 at 13:37 Comment(8)
What is the point of using RecyclerView if you do not want scrolling?Paulinepauling
@CommonsWare, I just want to disable it temporarily, for instance, while I'm doing a custom animation with one of its children.Meteoritics
Ah, OK, that makes sense. I'd've probably put a transparent View over top of the RecyclerView, toggling between VISIBLE and GONE as needed, but off the cuff your approach seems reasonable.Paulinepauling
Hope this helps find a better solution.Indecorum
@CommonsWare, here's what I need it for, for example. I need to display images in RecyclerView one at a time, without partially visible images, only one in my viewport. And there are arrows on the left and on the right which user can navigate with. Depending on what image is currently displayed (they are of various types), some things outside RecyclerView are triggered. It's the design our customers want.Redwood
@Paulinepauling I need to disable scrolling to also have up/down swipe directions. I use grid layout, not a list, and the items are all sized such that they are visible on the screen.Anthesis
Id I want to dynamically displaying all items of the recycle view under a big scrollview, then disabling the scrolling is helpful .Cerous
IMO there is a lot of use in using a RecyclerView without scroll. Maybe this is just me but the RecyclerView adapter offers a simple way to dynamically inflate different types of views with memory efficiency. I do have a custom LinearLayout , but it requires a lot more code to handle lifecycles, viewTypes, items ID's and ListDIffer adapters... with custom animations...etc... Also a list is almost always accompanied by a header with titles and menus, etc.. and all of those items are most certainly part of the List in a bigger scrollable view.Jetliner
C
473

You should override the layoutManager of your recycleView for this. This way it will only disable scrolling, none of the other functionalities. You will still be able to handle click or any other touch events. For example:-

Original:

public class CustomGridLayoutManager extends LinearLayoutManager {
    private boolean isScrollEnabled = true;

    public CustomGridLayoutManager(Context context) {
        super(context);
    }

    public void setScrollEnabled(boolean flag) {
        this.isScrollEnabled = flag;
    }

    @Override
    public boolean canScrollVertically() {
        //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
        return isScrollEnabled && super.canScrollVertically();
    }
}

Here using "isScrollEnabled" flag you can enable/disable scrolling functionality of your recycle-view temporarily.

Also:

Simple override your existing implementation to disable scrolling and allow clicking.

linearLayoutManager = new LinearLayoutManager(context) {
    @Override
    public boolean canScrollVertically() {
        return false;
    }
};

In Kotlin:

object : LinearLayoutManager(this) { override fun canScrollVertically() = false }
Consumptive answered 3/12, 2015 at 7:24 Comment(9)
This should be the correct answer as it disables scrolling while allowing me to click.Stercoraceous
Disabling scrolling on the default LayoutMangers should already exist, a user of the API should not have to do this. Thanks for the answer though!Wickerwork
i changed this to extend gridlayout it works but when i lock the scroll it jumps to the topAhab
What if I want to disable scrolling only from a certain item ? Meaning you can scroll down (or up) to it, but then get blocked, till I re-enable it again?Terrenceterrene
This also disables smoothScrollToPositionScoggins
you add kotlin version object :LinearLayoutManager(this){ override fun canScrollVertically(): Boolean { return false } }Saporific
Can you please describe fully the Kotlin way of overriding the layout manager?Marismarisa
how to disable scrolling for gridlayout manager?Pontus
Is it possible to disable scrolling while keeping the LinearLayout height at maximum?Kisor
I
214

The real answer is

recyclerView.setNestedScrollingEnabled(false);

More info in documentation

Isabelisabelita answered 3/2, 2016 at 15:14 Comment(6)
This will only disable nested scrolling, not all scrolling. 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.Oram
@Oram I believe recyclerView.setHasFixedSize(true) does the job for that. Edit: I also use this in conjuction with setFillViewport(true) so I'm not actually sure which one of the two fixes it.Variola
This works fine for me, but my "RecyclerView" was inside a Fragment layout using "ScrollView", so I had to change the "ScrollView" by "NestedScrollView", as described here: https://mcmap.net/q/100963/-recyclerview-inside-scrollview-some-items-are-not-shownCaddis
Remember to use the full class name for NestedScrollView: android.support.v4.widget.NestedScrollView, as described here, by chessdork: #37846745Tune
After spending 4 hours to trying to figure out what is wrong this solved my issue. In my case I am using a recyclerview inside of a MotionLayout. And I only added a swipe area to drag up by adding motion:touchAnchorId="@id/swipe_area". It works normally but also triggered when touched recyclerview's empty areas. Be careful when using motionLayout with other swipable elements.Shanon
This is the best answer for my case, the LinearLayoutManager.canScrollVertically() do not work same way as this. This method dispatched touch event to it parent view to handle.Driveway
P
171

For API 21 and above:

No java code needed. You can set android:nestedScrollingEnabled="false" in xml:

<android.support.v7.widget.RecyclerView
     android:id="@+id/recycler"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipToPadding="true"
     android:nestedScrollingEnabled="false"
     tools:listitem="@layout/adapter_favorite_place">
Pretzel answered 2/2, 2017 at 8:9 Comment(7)
I think this should be the accepted answer, without any effort in class you can disable the scrolling and yet the touch is allowed in the layout.Ratty
What for APIs below 21 ??Burgener
@pic for lower APIs you can use : recyclerView.setNestedScrollingEnabled(false);Pretzel
Accepted answer for me.Ale
You should also highlight the caveats associated with your answer. android:nestedScrollingEnabled="false" will make the onBindViewHolder called for all the items at once and the items will not get recycled which is not good if the data is large.Madel
this is the best and most straightforward answer, which also avoids unnecessary code pollution, and endless class extending patterns.Restaurateur
Well, this doesn't work. I guess this only works for nested views. But recyclerview itself is still scrollable.Apples
M
59

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 
Meteoritics answered 29/5, 2015 at 13:37 Comment(8)
Does this disable the item clicking too?Snowwhite
@JahirFiquitiva Yes. "This is an empty RecyclerView.OnItemTouchListener stealing every touch event"Cornish
this also disables parent view's scroll as wellDebbi
This disables item click tooSeclude
Why use a hackish workaround (with side effects) when there is a clean solution ? Just override the LayoutManager (see other answers)Oram
@Oram I chose this solution over the accepted answer because it only blocks inputs from the user, and still allows me to call the smoothScrollBy() method. So I can disable user scrolling, run some animations in the recyclerview, and re-enable it afterwards.Fallingout
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.Kismet
It might be hackish, but if the reason you want to disable the scroll was due to interfactions an onTouch handler to begin with, it's the right solution.Ketti
C
47

This works for me:

  recyclerView.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          return true;
      }
  });
Countercurrent answered 6/10, 2015 at 0:52 Comment(6)
This disables all touch.Stercoraceous
Nice trick! To re-enable again, just re-set the onTouchListener's onTouch to return falseAdductor
uhm, but there is a warning Custom view 'RecyclerView' has setOnTouchListener called on it but does not override performClickAdductor
If you are receiving the same warning that @Adductor mentioned in the comment above then take a look at this question's answers: #46135749Durazzo
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.Kismet
Kotlin short version products_carousel.setOnTouchListener { _, _ -> true}Harslet
T
26

As setLayoutFrozen is deprecated, You can disable scrolling by freezing your RecyclerView by using suppressLayout.

To freeze:

recyclerView.suppressLayout(true)

To unfreeze:

recyclerView.suppressLayout(false)
Taco answered 12/12, 2019 at 11:15 Comment(2)
This suppress animation of RecycleView itself as well and other stuff which is not acceptable if taking about only disable scrollHarslet
Working fine till dateIsaak
W
18
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            // Stop only scrolling.
            return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
        }
    });

Wane answered 25/2, 2016 at 10:2 Comment(4)
This aborts scrolling of smoothScrollToPosition() when touched.Radium
This is the best solution for me because it allows scrolling programatically but avoids user scrolling.Jotter
This is the best solution! thumbs up!Poitiers
Thank you, that's what I was looking for. And other one can also adjust the condition so user scrolling is prevented at some times and not others (which is exactly what I need).Ketti
E
18

You can disable scrolling by freezing your RecyclerView.

To freeze: recyclerView.setLayoutFrozen(true)

To unfreeze: recyclerView.setLayoutFrozen(false)

Everyone answered 11/10, 2018 at 22:13 Comment(3)
Take a note: child views are not updated when RecyclerView is frozen. I need to disable scroll when there's enough room on the screen to show all items. Oh... What a nice Android API for this task...Hehre
Deprecated in API 28Vada
Its been replace with suppressLayout, but not does a lot more than prevent scrolling. I need to suppress the scrolling from user interaction, but I need it to scroll programmatically, and make other changes this prevents. It's the right solution for some situations, but not others.Ketti
C
16

In Kotlin, if you don't want to create an extra class just for setting one value, you can create anonymous class from LayoutManager:

recyclerView.layoutManager = object : LinearLayoutManager(context) {
    override fun canScrollVertically(): Boolean = false
}
Clein answered 8/5, 2020 at 9:27 Comment(0)
C
15

There is a simple answer.

LinearLayoutManager lm = new LinearLayoutManager(getContext()) {
                @Override
                public boolean canScrollVertically() {
                    return false;
                }
            };

The above code disables RecyclerView's verticall scrolling.

Chisolm answered 1/1, 2019 at 13:13 Comment(0)
A
14

Create class which extend RecyclerView class

public class NonScrollRecyclerView extends RecyclerView {

    public NonScrollRecyclerView(Context context) {
        super(context);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}

This will disable the scroll event, but not the click events

Use this in your XML do the following:

  <com.yourpackage.xyx.NonScrollRecyclerView 
     ...
     ... 
  />
Axiology answered 28/8, 2016 at 9:55 Comment(6)
Thanks! This all is needed when we want to allow recycler view to take full height according to contents without internal scrolling. :)Block
But if this recycler view is in a scrolling view (e.g.ScrollView) then the layout manager should override canScrollVertically() method returning false from it.Block
@RahulRastogi use NestedScrollView instead of ScrollViewAxiology
Hey @AshishMangave , Please tell how to enable it again programmaticallyCurley
@Curley we can’t do this programatically. bcz we directly override recyclerview ’s onMeasure method.you can try for this recyclerView.setNestedScrollingEnabled(false) .this will help youAxiology
@Ashish, This is for stop vertical scroll, please tell me how to stop horizontal scrollCurley
S
13

If you just disable only scroll functionality of RecyclerView then you can use setLayoutFrozen(true); method of RecyclerView. But it can not be disable touch event.

your_recyclerView.setLayoutFrozen(true);
Scarcity answered 14/7, 2018 at 7:4 Comment(3)
this method is deprecated. can you suggest another one?Dowden
Deprecated in API 28Vada
For deprecation, use suppressLayout(true) insteadHellgrammite
E
12

Wrote a kotlin version:

class NoScrollLinearLayoutManager(context: Context?) : LinearLayoutManager(context) {
    private var scrollable = true

    fun enableScrolling() {
        scrollable = true
    }

    fun disableScrolling() {
        scrollable = false
    }

    override fun canScrollVertically() =
            super.canScrollVertically() && scrollable


    override fun canScrollHorizontally() =
            super.canScrollVertically()

 && scrollable
}

usage:

recyclerView.layoutManager = NoScrollLinearLayoutManager(context)
(recyclerView.layoutManager as NoScrollLinearLayoutManager).disableScrolling()
Enteric answered 4/11, 2017 at 14:39 Comment(0)
T
7

in XML :-

You can add

android:nestedScrollingEnabled="false"

in the child RecyclerView layout XML file

or

in Java :-

childRecyclerView.setNestedScrollingEnabled(false);

to your RecyclerView in Java code.

Using ViewCompat (Java) :-

childRecyclerView.setNestedScrollingEnabled(false); will work only in android_version>21 devices. to work in all devices use the following

ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);

Typewrite answered 29/3, 2018 at 6:39 Comment(1)
Excelent, all apis covered, should be powered up.Beer
E
6

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)

Extinguisher answered 21/9, 2015 at 11:29 Comment(0)
F
5

Extend the LayoutManager and override canScrollHorizontally()and canScrollVertically() to disable scrolling.

Be aware that inserting items at the beginning will not automatically scroll back to the beginning, to get around this do something like:

  private void clampRecyclerViewScroll(final RecyclerView recyclerView)
  {
    recyclerView.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
    {
      @Override
      public void onItemRangeInserted(int positionStart, int itemCount)
      {
        super.onItemRangeInserted(positionStart, itemCount);
        // maintain scroll position at top
        if (positionStart == 0)
        {
          RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
          if (layoutManager instanceof GridLayoutManager)
          {
            ((GridLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }else if(layoutManager instanceof LinearLayoutManager)
          {
            ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }
        }
      }
    });
  }
Forelimb answered 21/8, 2015 at 12:7 Comment(1)
this disables also smoothScrollToPositionScoggins
K
5

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) {

    }
});
Kolk answered 2/12, 2015 at 23:46 Comment(3)
For some reason, you have to click just right, without moving for this to work.Stercoraceous
Good point, @JaredBurrows. This is because we're disregarding ACTION_MOVE. For touch to feel natural, there's some give between touching, and slight movement on the screen. Unfortunately, I wasn't able to solve for that problem.Kolk
Thanks, exactly what I needed!Starstarboard
G
4

You should just add this line:

recyclerView.suppressLayout(true)
Godolphin answered 18/7, 2020 at 13:15 Comment(1)
Tells the RecyclerView to suppress all layout and scroll calls until layout suppression is disabled. refer to docsGarniture
G
3

For some reason @Alejandro Gracia answer starts working only after a few second. I found a solution that blocks the RecyclerView instantaneously:

recyclerView.addOnItemTouchListener(new 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) {
            }
        });
Gastrocnemius answered 28/10, 2015 at 16:20 Comment(0)
R
3

Override onTouchEvent() and onInterceptTouchEvent() and return false if you don't need OnItemTouchListener at all. This does not disable OnClickListeners of ViewHolders.

public class ScrollDisabledRecyclerView extends RecyclerView {
    public ScrollDisabledRecyclerView(Context context) {
        super(context);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return false;
    }
}
Radium answered 18/4, 2016 at 8:55 Comment(0)
G
3

Just add this to your recycleview in xml

 android:nestedScrollingEnabled="false"

like this

<android.support.v7.widget.RecyclerView
                    android:background="#ffffff"
                    android:id="@+id/myrecycle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:nestedScrollingEnabled="false">
Geordie answered 29/1, 2018 at 14:24 Comment(1)
awesome solutionGouache
U
3

Add

android:descendantFocusability="blocksDescendants"

in your child of SrollView or NestedScrollView (and parent of ListView, recyclerview and gridview any one)

Unwearied answered 6/4, 2018 at 4:47 Comment(0)
F
3

There is a more straightforward way to disable scrolling (technically it is more rather interception of a scrolling event and ending it when a condition is met), 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.

Fleam answered 24/7, 2018 at 16:7 Comment(2)
stopScroll() is not to freeze the scroll, it's just to halt/stop scrolling recyclerview.Prescriptible
@FARID, yes, this method just stops any scroll in progress, and in this particular case, it does that every time when a user tries to scroll RecyclerView content with isItemSelected set to true. Otherwise, you would need a custom RecyclerView to disable scrolling for good and I wanted to avoid it since I needed just a little extra functionality, which this solution provides.Fleam
B
2

I have been struggling in this issue for some hour, So I would like to share my experience, For the layoutManager solution it is fine but if u want to reEnable scrolling the recycler will back to top.

The best solution so far (for me at least) is using @Zsolt Safrany methode but adding getter and setter so you don't have to remove or add the OnItemTouchListener.

As follow

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    boolean isEnable = true;

    public RecyclerViewDisabler(boolean isEnable) {
        this.isEnable = isEnable;
    }

    public boolean isEnable() {
        return isEnable;
    }

    public void setEnable(boolean enable) {
        isEnable = enable;
    }

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

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

   @Override
   public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept){}
 }

Usage

RecyclerViewDisabler disabler = new RecyclerViewDisabler(true);
feedsRecycler.addOnItemTouchListener(disabler);

// TO ENABLE/DISABLE JUST USE THIS
disabler.setEnable(enable);
Borreri answered 12/7, 2016 at 9:14 Comment(0)
M
2

You can add this line after setting your adapter

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

Now your recyclerview will work with smooth scrolling

Marshland answered 24/11, 2018 at 9:8 Comment(0)
B
2

For whom want's to just prevent the user to scroll the RecyclerView, without loose the smoothScrollToPosition or any other "go to position" method, I'd recommend rather extending the RecyclerView class, overriding the onTouchEvent. Like this:

            public class HardwareButtonsRecyclerView extends RecyclerView {
            
                    public HardwareButtonsRecyclerView(@NonNull Context context) {
                        super(context);
                    }
            
                    public HardwareButtonsRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
                        super(context, attrs);
                    }
            
                    public HardwareButtonsRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                        super(context, attrs, defStyleAttr);
                    }
            
                @Override
                public boolean onTouchEvent(MotionEvent e) {
                    return false;
                }
            }
Bildungsroman answered 10/8, 2020 at 17:35 Comment(0)
B
2

At activity's onCreate method, you can simply do:

recyclerView.stopScroll()

and it stops scrolling.

Bibeau answered 30/9, 2020 at 8:18 Comment(0)
I
1

Here is how I did it with data binding:

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipChildren="false"
                android:onTouch="@{(v,e) -> true}"/>

In place of the "true" I used a boolean variable that changed based on a condition so that the recycler view would switch between being disabled and enabled.

Iconoduly answered 15/6, 2017 at 19:3 Comment(0)
H
1

Came across with a fragment that contains multiple RecycleView so I only need one scrollbar instead of one scrollbar in each RecycleView.

So I just put the ScrollView in the parent container that contains the 2 RecycleViews and use android:isScrollContainer="false" in the RecycleView

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"
    android:isScrollContainer="false" />
Hurst answered 9/1, 2018 at 6:34 Comment(0)
S
1

For stop scrolling by touch but keep scrolling via commands :

if (appTopBarMessagesRV == null) { appTopBarMessagesRV = findViewById(R.id.mainBarScrollMessagesRV);

        appTopBarMessagesRV.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

                if ( rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING)
                {
                     // Stop  scrolling by touch

                    return false;
                }
                return  true;
            }
        });
    }
Sandbag answered 25/1, 2020 at 18:0 Comment(0)
P
1

You can creat a Non Scrollable Recycler View which extends a Recycler View class, as follows:

import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

public class NonScrollRecyclerView extends RecyclerView {

    public NonScrollRecyclerView(Context context) {
        super(context);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasure, int heightMeasure) {
        int heightMeasureCustom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasure, heightMeasureCustom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}
Parvati answered 31/7, 2021 at 22:6 Comment(0)
M
1

Summing up answers on this question.

The easiest and the best way to disable scroll of the recyclerView:

yourRecyclerView.layoutmanager = object : LinearLayoutManager(context) {
        override fun canScrollVertically(): Boolean = false
    }

The following solutions works if recyclerView is put inside nestedScrollView:

yourRecyclerView.isNestedScrollingEnabled = false

android:descendantFocusability="blocksDescendants"

android:nestedScrollingEnabled="false"

Note: each solution works only if recyclerView is put inside nestedScrollView.

Meet answered 19/9, 2023 at 5:7 Comment(0)
B
0

MAY 2022

This way worked for me after a lot of tries in new versions of android and APIs.

The New Answer With Kotlin

  1. create a class called ScrollDisabledRecyclerView and put codes like this:

class ScrollDisabledRecyclerView : RecyclerView {

constructor(context: Context?) : super(context!!)
constructor(context: Context?, @Nullable attrs: AttributeSet?) : super(context!!, attrs)
constructor(context: Context?, @Nullable attrs: AttributeSet?, defStyle: Int) : super(
    context!!,
    attrs,
    defStyle
)

override fun onTouchEvent(e: MotionEvent): Boolean {
    return e.action == MotionEvent.ACTION_MOVE
}

override fun onInterceptTouchEvent(e: MotionEvent): Boolean {
    return false
}  }
  1. use this class in your XML instead of RecyclerView (this class is extended from it):
 <info.sanaebadi.ScrollDisabledRecyclerView

        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:clipToPadding="true"
        tools:listitem="@layout/multiple_questions_row" />
  1. and at last, handle the next and previous with buttons in MainActiviy like this:

note: I AM USING ViewBinding

binding.buttonNextQuestion.setOnClickListener {
            val totalItemCount: Int = binding.recyclerView.adapter!!.itemCount
            if (totalItemCount <= 0) return@setOnClickListener
            val lastVisibleItemIndex: Int = linearLayoutManager.findLastVisibleItemPosition()
            if (lastVisibleItemIndex >= totalItemCount) return@setOnClickListener
            linearLayoutManager.smoothScrollToPosition(
                binding.recyclerView,
                null,
                lastVisibleItemIndex + 1
            )

        }
        binding.buttonPreviousQuestion.setOnClickListener {
            val firstVisibleItemIndex: Int =
                linearLayoutManager.findFirstCompletelyVisibleItemPosition()
            if (firstVisibleItemIndex > 0) {
                linearLayoutManager.smoothScrollToPosition(
                    binding.recyclerView,
                    null,
                    firstVisibleItemIndex - 1
                )
            }
        }
Bicorn answered 9/5, 2022 at 6:2 Comment(0)
E
0

Now the set recyclerView.setLayoutFrozen(true); // for disabling scrolling of recycler view is deprecated use recyclerView.suppressLayout(true)

Earthward answered 24/8, 2023 at 10:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.