ventajas usar studio recyclerview for example ejemplo cuando cardview card and android android-recyclerview

android - usar - Cómo deshabilitar el desplazamiento de RecyclerView, excepto mediante programación



recyclerview android studio example (6)

Tengo un RecyclerView con un LinearLayoutManager en orientación HORIZONTAL . Cada elemento en él puede tener elementos interactivos (incluidos los ScrollView verticales). ¿Hay alguna manera de hacer que el RecyclerView ignore fácilmente cualquier intento del usuario de desplazar o lanzar el RecyclerView horizontalmente sin interceptar eventos táctiles a los niños?

Estoy controlando programáticamente el desplazamiento del RecyclerView que funciona muy bien hasta que el usuario lo arroja.

He intentado algo muy simple donde la idea es cuando llamo a smoothScrollToPosition en respuesta a algún evento, habilito el desplazamiento y deshabilito los eventos táctiles hasta que el desplazamiento se establece. Me gusta esto:

private class NoScrollHorizontalLayoutManager extends LinearLayoutManager { ScrollingTouchInterceptor interceptor = new ScrollingTouchInterceptor(); protected boolean canScroll; public NoScrollHorizontalLayoutManager(Context ctx) { super(ctx, LinearLayoutManager.HORIZONTAL, false); } public RecyclerView.OnItemTouchListener getInterceptor() { return interceptor; } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { canScroll = true; super.smoothScrollToPosition(recyclerView, state, position); } @Override public void onScrollStateChanged(int state) { super.onScrollStateChanged(state); if(state == RecyclerView.SCROLL_STATE_IDLE) { canScroll = false; } } @Override public boolean canScrollHorizontally() { return canScroll; } public class ScrollingTouchInterceptor implements RecyclerView.OnItemTouchListener { @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { return canScrollHorizontally(); } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } } }

Y úsalo así ...

NoScrollHorizontalLayoutManager layout = new NoScrollHorizontalLayoutManager(context); recycler.setLayoutManager(layout); recycler.addOnItemTouchListener(layout.getInterceptor());

que en realidad casi funciona ... pero aún puedo arruinar el desplazamiento programático tocando la pantalla cuando el desplazamiento suave está en movimiento. claramente me estoy perdiendo algo obvio o hay una manera mucho más inteligente de hacer esto.

ACTUALIZAR la solución que no es RecyclerView se encontró aquí: ¿Cómo deshabilitar la paginación deslizando el dedo en ViewPager pero aún así se puede deslizar programáticamente?

/** * ViewPager that doesn''t allow swiping. */ public class NonSwipeableViewPager extends ViewPager { public NonSwipeableViewPager(Context context) { super(context); } public NonSwipeableViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { // Never allow swiping to switch between pages return false; } @Override public boolean onTouchEvent(MotionEvent event) { // Never allow swiping to switch between pages return false; } }


Al invalidar onInterceptTouchEvent, se evita el comportamiento de detención al hacer clic.

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


Lo primero, no creo que esto se pueda lograr de manera no programática.

Modo 1: simple: deshabilite la otra vista basada en el toque.

Si el usuario toca el padre, deshabilite el desplazamiento de las vistas secundarias. viceversa también

Pedazo de código para hacer esto.

recyclerView.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View p_v, MotionEvent p_event) { yourChildView.getParent().requestDisallowInterceptTouchEvent(false); return false; } });

Forma 2: ya que tiene pequeños problemas en su implementación. Si lo publicas, alguien puede arreglar eso también.


Esto le da el efecto de continuidad.

recyclerView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { recyclerView.smoothScrollToPosition(position); return true; } else if (action == MotionEvent.ACTION_UP) { recyclerView.smoothScrollToPosition(position); return true; } return false; } });


recyclerView.setNestedScrollingEnabled(false);

Para más información ver documentation .


android:nestedScrollingEnabled="false"

Haga lo anterior en el archivo xml, en el TAG RecyclerView.


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