studio recyclerview item ejemplo bottom android scroll android-recyclerview

android - item - Desplácese hacia RecyclerView para mostrar el elemento seleccionado en la parte superior



recyclerview scroll to position (14)

// Elemento de desplazamiento pos

linearLayoutManager.scrollToPositionWithOffset(pos, 0);

Estoy buscando una manera de desplazar un RecyclerView para mostrar el elemento seleccionado en la parte superior.

En un ListView pude hacer eso usando scrollTo(x,y) y obteniendo la parte superior del elemento que necesita ser centrado.

Algo como:

@Override public void onItemClick(View v, int pos){ mylistView.scrollTo(0, v.getTop()); }

El problema es que RecyclerView devuelve un error al usar su método scrollTo diciendo

RecyclerView no admite el desplazamiento a una posición absoluta

¿Cómo puedo desplazar un RecyclerView para colocar el elemento seleccionado en la parte superior de la vista?


En mi caso, mi RecyclerView tiene una parte superior acolchada como esta

<android.support.v7.widget.RecyclerView ... android:paddingTop="100dp" android:clipToPadding="false" />

Luego, para desplazar un elemento hacia arriba, necesito

recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());


Lo que hice para restaurar la posición de desplazamiento después de actualizar el RecyclerView al hacer clic en el botón:

if (linearLayoutManager != null) { index = linearLayoutManager.findFirstVisibleItemPosition(); View v = linearLayoutManager.getChildAt(0); top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop()); Log.d("TAG", "visible position " + " " + index); } else{ index = 0; } linearLayoutManager = new LinearLayoutManager(getApplicationContext()); linearLayoutManager.scrollToPositionWithOffset(index, top);

obtener el desplazamiento del primer elemento visible desde la parte superior antes de crear el objeto linearLayoutManager y después de instanciarlo, se llamó al scrollToPositionWithOffset del objeto LinearLayoutManager.


Ninguna de las respuestas explica cómo mostrar los últimos elementos en la parte superior. Por lo tanto, las respuestas funcionan solo para elementos que todavía tienen suficientes elementos encima o debajo de ellos para llenar el RecyclerView restante. Por ejemplo, si hay 59 elementos y se selecciona un 56º elemento, debe estar en la parte superior como en la imagen a continuación:

Podríamos manejar esos casos usando linearLayoutManager.scrollToPositionWithOffset(pos, 0) y una lógica adicional en el Adapter de RecyclerView , agregando un margen personalizado debajo del último elemento (si el último elemento no es visible, significa que hay suficiente espacio para llenar el RecyclerView ) El margen personalizado podría ser una diferencia entre la altura de la vista raíz y la altura del elemento. Entonces, su Adapter para RecyclerView se vería de la siguiente manera:

View firstView = mRecyclerView.getChildAt(0); int toY = firstView.getTop(); int firstPosition = mRecyclerView.getChildAdapterPosition(firstView); View thisView = mRecyclerView.getChildAt(thisPosition - firstPosition); int fromY = thisView.getTop(); mRecyclerView.smoothScrollBy(0, fromY - toY);


No sé por qué no encontré la mejor respuesta, pero es realmente simple.

recyclerView.smoothScrollToPosition(position);

Sin errores

Crea animaciones


Prueba lo que funcionó para mí genial!

Crear una variable private static int displayedposition = 0;

Ahora para la posición de su RecyclerView en su actividad.

myRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); LinearLayoutManager llm = (LinearLayoutManager) myRecyclerView.getLayoutManager(); displayedposition = llm.findFirstVisibleItemPosition(); } });

Coloque esta declaración donde desee que coloque el sitio anterior que se muestra en su vista.

LinearLayoutManager llm = (LinearLayoutManager) mRecyclerView.getLayoutManager(); llm.scrollToPositionWithOffset(displayedposition , youList.size());

Bueno, eso es todo, funcionó bien para mí


Si está buscando LinearLayout Manager vertical, puede lograr un desplazamiento suave utilizando un LinearSmoothScroller personalizado:

import android.content.Context; import android.graphics.PointF; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearSmoothScroller; import android.support.v7.widget.RecyclerView; public class SnappingLinearLayoutManager extends LinearLayoutManager { public SnappingLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()); smoothScroller.setTargetPosition(position); startSmoothScroll(smoothScroller); } private class TopSnappedSmoothScroller extends LinearSmoothScroller { public TopSnappedSmoothScroller(Context context) { super(context); } @Override public PointF computeScrollVectorForPosition(int targetPosition) { return SnappingLinearLayoutManager.this .computeScrollVectorForPosition(targetPosition); } @Override protected int getVerticalSnapPreference() { return SNAP_TO_START; } } }

use una instancia del layoutmanager en la vista de reciclaje y luego llame a recyclerView.smoothScrollToPosition(pos); se desplazará suavemente a la posición seleccionada a la parte superior de la vista del reciclador


Si está utilizando LinearLayoutManager o Staggered GridLayoutManager , cada uno tiene un método scrollToPositionWithOffset que toma tanto la posición como el desplazamiento del inicio del elemento desde el inicio de RecyclerView , que parece que lograría lo que necesita (configurando el el desplazamiento a 0 debe alinearse con la parte superior).

Por ejemplo:

//Scroll item 2 to 20 pixels from the top linearLayoutManager.scrollToPositionWithOffset(2, 20);


Solo necesita llamar a recyclerview.scrollToPosition(position) . ¡Esta bien!

Si desea llamarlo en el adaptador, simplemente deje que su adaptador tenga la instancia de recyclerview o la actividad o fragmento que contiene recyclerview, que implementa el método getRecyclerview() en ellos.

Espero que te pueda ayudar.


Utilizo el siguiente código para desplazar suavemente un elemento (thisView) hacia la parte superior.
Funciona también para GridLayoutManager con vistas de diferentes alturas:

View firstView = mRecyclerView.getChildAt(0); int toY = firstView.getTop(); int firstPosition = mRecyclerView.getChildAdapterPosition(firstView); View thisView = mRecyclerView.getChildAt(thisPosition - firstPosition); int fromY = thisView.getTop(); mRecyclerView.smoothScrollBy(0, fromY - toY);

Parece funcionar lo suficientemente bien como para una solución rápida.


desplazarse en una posición particular
y esto me ayudó mucho. por clic oyente puede obtener la posición en su adaptador

layoutmanager.scrollToPosition(int position);


lo mismo con el regulador de velocidad

public class SmoothScrollLinearLayoutManager extends LinearLayoutManager { private static final float MILLISECONDS_PER_INCH = 110f; private Context mContext; public SmoothScrollLinearLayoutManager(Context context,int orientation, boolean reverseLayout) { super(context,orientation,reverseLayout); mContext = context; } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()){ //This controls the direction in which smoothScroll looks for your view @Override public PointF computeScrollVectorForPosition(int targetPosition) { return new PointF(0, 1); } //This returns the milliseconds it takes to scroll one pixel. @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; } }; smoothScroller.setTargetPosition(position); startSmoothScroll(smoothScroller); } private class TopSnappedSmoothScroller extends LinearSmoothScroller { public TopSnappedSmoothScroller(Context context) { super(context); } @Override public PointF computeScrollVectorForPosition(int targetPosition) { return SmoothScrollLinearLayoutManager.this .computeScrollVectorForPosition(targetPosition); } @Override protected int getVerticalSnapPreference() { return SNAP_TO_START; } } }


simplemente llame a este método simplemente:

((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(yourItemPosition,0);

en lugar de:

recyclerView.scrollToPosition(yourItemPosition);


If you want to scroll automatic without show scroll motion then you need to write following code: **=> mRecyclerView.getLayoutManager().scrollToPosition(position);** If you want to display scroll motion then you need to add following code. =>Step 1: You need to declare SmoothScroller. RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(this.getApplicationContext()) { @Override protected int getVerticalSnapPreference() { return LinearSmoothScroller.SNAP_TO_START; } }; =>step 2: You need to add this code any event you want to perform scroll to specific position. =>First you need to set target position to SmoothScroller. **smoothScroller.setTargetPosition(position);** =>Then you need to set SmoothScroller to LayoutManager. **mRecyclerView.getLayoutManager().startSmoothScroll(smoothScroller);**