wake-up-neo.net

Deaktivieren des RecyclerView-Scrollen

Ich kann das Scrollen in der RecyclerView nicht deaktivieren. Ich habe versucht, rv.setEnabled(false) aufzurufen, kann aber trotzdem scrollen.

Wie kann ich das Blättern deaktivieren?

145
Zsolt Safrany

Sie sollten dazu den Layoutmanager Ihres Recycleview überschreiben. Auf diese Weise wird nur das Scrollen deaktiviert, keine der anderen Funktionen. Sie können weiterhin mit Klick- oder anderen Berührungsereignissen umgehen. Zum Beispiel:-

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();
 }
}

Mit dem Flag "isScrollEnabled" können Sie die Scrollfunktion Ihrer Recyclingansicht vorübergehend aktivieren/deaktivieren.

Ebenfalls:

Überschreiben Sie einfach Ihre vorhandene Implementierung, um das Scrollen zu deaktivieren und das Klicken zuzulassen.

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

Die wirkliche Antwort lautet: 

recyclerView.setNestedScrollingEnabled(false);

Mehr Infos in Dokumentation

106
Bozic Nebojsa

Dies ist eine etwas hackige Problemumgehung, aber es funktioniert; Sie können das Scrollen in RecyclerView aktivieren/deaktivieren.

Dies ist ein leerer RecyclerView.OnItemTouchListener, der jedes Berührungsereignis stiehlt, wodurch das Ziel RecyclerView deaktiviert wird.

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

    }
}

Es benutzen:

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 
41
Zsolt Safrany

Für API 21 und höher:

Kein Java-Code benötigt. Sie können Android:nestedScrollingEnabled="false".__ einstellen. 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">
27
Milad Faridnia

Das funktioniert für mich: 

  recyclerView.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          return true;
      }
  });
27
alxgarcia

Erstellen Sie eine Klasse, die die Klasse RecyclerView erweitert

    public class NonscrollRecylerview extends RecyclerView {

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

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

public NonscrollRecylerview(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();
}
}

Dadurch wird das Bildlaufereignis deaktiviert, nicht jedoch die Klickereignisse

Verwenden Sie dies in Ihrem XML-Objekt wie folgt:

  <com.yourpackage.xyx.NonscrollRecylerview 
 ...
 ... >

 ...
 ...

</com.yourpackage.xyz.NonscrollRecylerview >
8
Ashish

Wenn Sie nur die only-Scrollfunktion von RecyclerView deaktivieren, können Sie die setLayoutFrozen(true);-Methode von RecyclerView verwenden. Es kann jedoch kein Berührungsereignis deaktiviert werden.

your_recyclerView.setLayoutFrozen(true);
6
Ekta Bhawsar

Eine andere Alternative ist setLayoutFrozen, aber es kommt mit einer Reihe anderer Nebenwirkungen.

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

5
Taig

Sie können das Scrollen deaktivieren, indem Sie Ihren RecyclerView einfrieren.

Einfrieren: recyclerView.setLayoutFrozen(true)

Entfrosten: recyclerView.setLayoutFrozen(false)

4
Virat Singh

Erweitern Sie LayoutManager und überschreiben Sie canScrollHorizontally()und canScrollVertically(), um das Scrollen zu deaktivieren.

Beachten Sie, dass beim Einfügen von Elementen am Anfang nicht automatisch ein Bildlauf an den Anfang vorgenommen wird. Gehen Sie dazu wie folgt vor:

  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);
          }
        }
      }
    });
  }
4
Aidanvii
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            // Stop only scrolling.
            return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
        }
    });

3
rajesh

Ich weiß, dass dies bereits eine akzeptierte Antwort hat, aber die Lösung berücksichtigt keinen Anwendungsfall, auf den ich gestoßen bin.

Ich brauchte speziell ein Header-Element, das noch anklickbar war, aber den Scroll-Mechanismus der RecyclerView deaktiviert hat. Dies kann mit dem folgenden Code erreicht werden:

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

                    }
                });
3
Ryan Simon

Schrieb eine 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
}

verwendungszweck:

recyclerView.layoutManager = NoScrollLinearLayoutManager(context)
(recyclerView.layoutManager as NoScrollLinearLayoutManager).disableScrolling()
3

Überschreiben Sie onTouchEvent () und onInterceptTouchEvent (), und geben Sie false zurück, wenn Sie OnItemTouchListener überhaupt nicht benötigen .. __ Dies deaktiviert OnClickListeners von ViewHolders nicht.

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;
    }
}
2
ypresto

Aus irgendeinem Grund funktioniert die Antwort von @Alejandro Gracia erst nach wenigen Sekunden. Ich fand eine Lösung, die die RecyclerView sofort blockiert:

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) {
            }
        });
2
vovahost

in XML: -

Du kannst hinzufügen

Android:nestedScrollingEnabled="false"

in der untergeordneten RecyclerView-Layout-XML-Datei

oder

in Java: -

childRecyclerView.setNestedScrollingEnabled(false);

zu Ihrem RecyclerView in Java code.

Mit ViewCompat (Java): -

childRecyclerView.setNestedScrollingEnabled(false); funktioniert nur auf Android_version> 21 Geräten. Um in allen Geräten zu arbeiten, gehen Sie wie folgt vor

ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);

2
jafarbtech

Ich habe in dieser Ausgabe einige Stunden lang Probleme gehabt, Daher möchte ich meine Erfahrung teilen.... Für die LayoutManager-Lösung ist dies in Ordnung, aber wenn Sie das Scrollen wieder aktivieren möchten, wird der Recycler nach oben zurückkehren.

Die beste Lösung bisher (zumindest für mich) ist die Verwendung von @Zsolt Safrany, wobei jedoch Getter und Setter hinzugefügt werden, damit Sie den OnItemTouchListener nicht entfernen oder hinzufügen müssen.

Wie folgt

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

Verwendungszweck 

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

// TO ENABLE/DISABLE JUST USE THIS
disabler.setEnable(enable);
1
Aladdin

Kam mit einem Fragment, das mehrere RecycleView enthält, herüber, so dass ich in jeder RecycleView nur eine Bildlaufleiste anstelle einer Bildlaufleiste benötige.

Also füge ich einfach die ScrollView in den übergeordneten Container, der die 2 RecycleViews enthält, und verwende Android:isScrollContainer="false" in der 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" />
0
pk028382

Es gibt eine einfachere Möglichkeit, das Scrollen zu deaktivieren, indem nur Standardfunktionen verwendet werden. RecyclerView hat die Methode addOnScrollListener(OnScrollListener listener). Wenn Sie diese Option verwenden, können Sie den Bildlauf stoppen, nur so:

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

Anwendungsfall: Nehmen wir an, Sie möchten das Scrollen deaktivieren, wenn Sie auf eines der Elemente in RecyclerView klicken, damit Sie einige Aktionen damit ausführen können, ohne durch ein versehentliches Scrollen zu einem anderen Element abgelenkt zu werden Wenn Sie fertig sind, klicken Sie einfach erneut auf das Objekt, um das Scrollen zu aktivieren. Dazu möchten Sie OnClickListener an jedes Element innerhalb von RecyclerView anhängen. Wenn Sie also auf ein Element klicken, wird isItemSelected von false in true umgeschaltet. Wenn Sie versuchen, einen Bildlauf durchzuführen, ruft RecyclerView automatisch die Methode onScrollStateChanged auf. Da isItemSelected auf true gesetzt ist, wird sie sofort angehalten, bevor RecyclerView die Möglichkeit hat, einen Bildlauf durchzuführen.

Hinweis: Um die Benutzerfreundlichkeit zu verbessern, versuchen Sie, GestureListener anstelle von OnClickListener zu verwenden, um accidental-Klicks zu verhindern.

0
Tim Jorjev

Sie können diese Zeile hinzufügen, nachdem Sie Ihren Adapter eingestellt haben

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

Jetzt funktioniert Ihr Recyclerview mit reibungslosem Scrollen

0
Atefeh Srch

So habe ich es mit der Datenbindung gemacht:

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

Anstelle von "true" habe ich eine boolesche Variable verwendet, die sich aufgrund einer Bedingung geändert hat, so dass die Recycler-Ansicht zwischen deaktiviert und aktiviert wechseln würde.

0
bwhite

Fügen Sie dies einfach zu Ihrer Recyclingansicht in XML hinzu

 Android:nestedScrollingEnabled="false"

so was

<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">
0
anas

Es gibt eine wirklich einfache Antwort.

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

Der obige Code deaktiviert den vertikalen Bildlauf von RecyclerView.

0
Emi Raz

Hinzufügen

Android:descendantFocusability="blocksDescendants"

in Ihrem Kind von SrollView oder NestedScrollView (und einem übergeordneten Element von ListView, RecyclingView und GridView)

0
Pankaj Talaviya