tutorial studio sgoliver recyclerview que imágenes implement con cardview card and android scroll android-recyclerview

android - studio - ¿Cómo deshabilitar el desplazamiento RecyclerView?



que es un recyclerview android (24)

No puedo desactivar el desplazamiento en RecyclerView . Intenté llamar a rv.setEnabled(false) pero aún puedo desplazarme.

¿Cómo puedo desactivar el desplazamiento?


Añadir

android:nestedScrollingEnabled="false"

en su hijo de SrollView o NestedScrollView (y padre de ListView, recyclerview y gridview cualquiera)


Anule onTouchEvent () y onInterceptTouchEvent () y devuelva false si no necesita OnItemTouchListener. Esto no deshabilita OnClickListeners de 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; } }


Así es como lo hice con el enlace de datos:

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

En lugar de "verdadero", utilicé una variable booleana que cambió en función de una condición para que la vista del reciclador cambiara entre estar deshabilitada y habilitada.


Crear clase que extienda la clase RecyclerView

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

Esto deshabilitará el evento de desplazamiento, pero no los eventos de clic

Use esto en su XML, haga lo siguiente:

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


Debe anular el administrador de diseño de su vista de reciclaje para esto. De esta manera solo deshabilitará el desplazamiento, ninguna de las otras funcionalidades. Aún podrá manejar clics o cualquier otro evento táctil. Por ejemplo:-

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

Aquí, usando el indicador "isScrollEnabled", puede habilitar / deshabilitar la funcionalidad de desplazamiento de su vista de reciclaje temporalmente.

También:

Simplemente anule su implementación existente para deshabilitar el desplazamiento y permitir hacer clic.

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


Encontré un fragmento que contiene múltiples RecycleView, por lo que solo necesito una barra de desplazamiento en lugar de una barra de desplazamiento en cada RecycleView.

Así que acabo de poner el ScrollView en el contenedor principal que contiene los 2 RecycleViews y uso android:isScrollContainer="false" en el 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" />


Escribió una versión de Kotlin:

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 }

uso:

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


Esta es una solución un poco complicada pero funciona; puede habilitar / deshabilitar el desplazamiento en RecyclerView .

Este es un RecyclerView.OnItemTouchListener vacío. RecyclerView.OnItemTouchListener roba cada evento táctil y deshabilita el RecyclerView objetivo.

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

Utilizándolo:

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


Esto funciona para mi:

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


Extienda el LayoutManager y anule canScrollHorizontally() y canScrollVertically() para deshabilitar el desplazamiento.

Tenga en cuenta que insertar elementos al principio no se desplazará automáticamente hacia el principio, para evitar esto haga algo como:

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


Hay una forma más directa de deshabilitar el desplazamiento (técnicamente es más bien la intercepción de un evento de desplazamiento y finalizarlo cuando se cumple una condición), utilizando solo la funcionalidad estándar. RecyclerView tiene el método llamado addOnScrollListener(OnScrollListener listener) , y con solo esto puede evitar que se desplace, así:

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

Caso de uso: supongamos que desea deshabilitar el desplazamiento cuando hace clic en uno de los elementos dentro de RecyclerView para poder realizar algunas acciones con él, sin distraerse desplazándose accidentalmente a otro elemento, y cuando haya terminado con él, simplemente haga clic en el elemento nuevamente para habilitar el desplazamiento. Para eso, querrá adjuntar OnClickListener a cada elemento dentro de RecyclerView , por lo que cuando hace clic en un elemento, alternaría isItemSelected de false a true . De esta manera, cuando intente desplazarse, RecyclerView llamará automáticamente al método onScrollStateChanged y dado que isItemSelected establece en true , se detendrá inmediatamente, antes de que RecyclerView tenga la oportunidad, bueno ... de desplazarse.

Nota: para una mejor usabilidad, intente usar GestureListener lugar de OnClickListener para evitar clics accidental .


Hay una respuesta realmente simple.

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

El código anterior deshabilita el desplazamiento vertical de RecyclerView.


He estado luchando en este problema durante una hora, por lo que me gustaría compartir mi experiencia. Para la solución layoutManager está bien, pero si desea volver a habilitar el desplazamiento, el reciclador volverá al principio.

La mejor solución hasta ahora (al menos para mí) es usar el método @Zsolt Safrany pero agregar getter y setter para que no tenga que quitar o agregar OnItemTouchListener.

De la siguiente manera

RecyclerViewDisabler disabler = new RecyclerViewDisabler(true); feedsRecycler.addOnItemTouchListener(disabler); // TO ENABLE/DISABLE JUST USE THIS disabler.setEnable(enable);

Uso

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


La respuesta REAL REAL es: Para API 21 y superior:

No se necesita código java. Puede configurar android:nestedScrollingEnabled="false" en xml:

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


La verdadera respuesta es

recyclerView.setNestedScrollingEnabled(false);

Más información en la documentation



Por alguna razón, la respuesta de @Alejandro Gracia comienza a funcionar solo después de unos segundos. Encontré una solución que bloquea el RecyclerView instantáneamente:

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


Puede agregar esta línea después de configurar su adaptador

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

Ahora su vista de reciclaje funcionará con desplazamiento suave


Puede deshabilitar el desplazamiento congelando su RecyclerView.

Para congelar: recyclerView.setLayoutFrozen(true)

Para descongelar: recyclerView.setLayoutFrozen(false)


Sé que esto ya tiene una respuesta aceptada, pero la solución no tiene en cuenta un caso de uso que encontré.

Específicamente, necesitaba un elemento de encabezado en el que todavía se pudiera hacer clic, pero deshabilité el mecanismo de desplazamiento de RecyclerView. Esto se puede lograr con el siguiente código:

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


Si solo deshabilita la funcionalidad de desplazamiento de RecyclerView , puede usar setLayoutFrozen(true); Método de RecyclerView . Pero no se puede desactivar el evento táctil.

your_recyclerView.setLayoutFrozen(true);


Simplemente agregue esto a su vista de reciclaje en xml

android:descendantFocusability="blocksDescendants"

Me gusta esto

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


en XML: -

Puedes añadir

android:nestedScrollingEnabled="false"

en el archivo XML de diseño RecyclerView secundario

o

en Java: -

childRecyclerView.setNestedScrollingEnabled(false);

a su RecyclerView en código Java.

Usando ViewCompat (Java): -

childRecyclerView.setNestedScrollingEnabled(false); solo funcionará en android_version> 21 dispositivos. para trabajar en todos los dispositivos use lo siguiente

ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);


recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { // Stop only scrolling. return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING; } });