stan malcolm
Estoy usando un administrador de diseño horizontal para mi RecyclerView
. necesito hacer RecyclerView
de la siguiente manera: cuando haga clic en algún elemento, haga un desplazamiento suave hasta esa posición y coloque ese elemento en el centro de RecyclerView
(si es posible, por ejemplo, 10 artículo de 20).
Entonces, no tengo ningún problema con smoothScrollToPosition()
pero cómo poner el artículo que en el centro de RecyclerView
???
¡Gracias!
usuario3680200
Si es posible.
Al implementar RecyclerView.SmoothScroller
método de onTargetFound(View, State, Action)
.
/**
* Called when the target position is laid out. This is the last callback SmoothScroller
* will receive and it should update the provided {@link Action} to define the scroll
* details towards the target view.
* @param targetView The view element which render the target position.
* @param state Transient state of RecyclerView
* @param action Action instance that you should update to define final scroll action
* towards the targetView
*/
abstract protected void onTargetFound(View targetView, State state, Action action);
Específicamente en LinearLayoutManager
con LinearSmoothScroller
:
public class CenterLayoutManager extends LinearLayoutManager {
public CenterLayoutManager(Context context) {
super(context);
}
public CenterLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CenterLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private static class CenterSmoothScroller extends LinearSmoothScroller {
CenterSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
}
}
-
extends LinearSmoothScroller
debe anularcomputeScrollVectorForPosition()
– Ninja
27 de diciembre de 2016 a las 7:02
-
funcionó impecable
– Eliseo Ocampos
21 de abril de 2017 a las 17:11
-
Perfecto, para los demas solo llamas
recyclerView.smoothScrollToPosition(position);
y no olvide configurar el administrador de diseñorecyclerView.setLayoutManager(layoutManager);
– Pete
9 de junio de 2017 a las 15:58
-
Donde es eso
onTargetFound()
función implementada?– Los errores suceden
24 de agosto de 2018 a las 11:05
-
Pero no entendí exactamente por qué mencionaste sobre este método.
onTargetFound()
?– Sirop4ik
31 de octubre de 2018 a las 8:55
王 能
Mejoras a la respuesta – no hay necesidad de anular el LinearLayoutManager
De la respuesta anterior:
public class CenterSmoothScroller extends LinearSmoothScroller {
public CenterSmoothScroller(Context context) {
super(context);
}
@Override
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
}
Aquí cómo usarlo:
RecyclerView.LayoutManager lm = new GridLayoutManager(...): // or whatever layout manager you need
...
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
lm.startSmoothScroll(smoothScroller);
-
Para otros que están confundidos como yo,
CenterSmoothScroller
es una clase que se encuentra en la respuesta aceptada.– rjr-aplicaciones
14 de febrero de 2019 a las 23:20
-
¡Aleluya! Pasó medio día probando un montón de formas complicadas de hacer esto y su solución funciona perfectamente. ¡Gracias!
– mjp66
18 de marzo de 2020 a las 23:25
-
¿Cómo obtendré la posición mientras declaro la vista del reciclador? Necesito colocar el elemento en el centro mientras el usuario desplaza el elemento usando D-Pad. @usuario8944115
– Aravind
28 de abril de 2020 a las 7:31
-
¡¡esto funcionó a las mil maravillas!! gracias, si no encuentra la clase, tal vez necesite actualizar sus dependencias, está bajo
androidx.recyclerview.widget.LinearSmoothScroller
– Javier
2 de julio de 2021 a las 9:46
-
Es una solución correcta y fácil. Gracias
– Trung Đoan
25 oct 2021 a las 5:30
En caso de que alguien necesite el Equivalente de Kotlin de la clase en la respuesta aceptada.
class CenterLayoutManager : LinearLayoutManager {
constructor(context: Context) : super(context)
constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State, position: Int) {
val centerSmoothScroller = CenterSmoothScroller(recyclerView.context)
centerSmoothScroller.targetPosition = position
startSmoothScroll(centerSmoothScroller)
}
private class CenterSmoothScroller(context: Context) : LinearSmoothScroller(context) {
override fun calculateDtToFit(viewStart: Int, viewEnd: Int, boxStart: Int, boxEnd: Int, snapPreference: Int): Int = (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2)
}
}
furkanbzkurt
Según la respuesta de @Boda, si desea controlar la velocidad de desplazamiento suave (para una mejor animación), puede usar lo siguiente:
class CenterLayoutManager : LinearLayoutManager {
constructor(context: Context) : super(context)
constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(
context,
orientation,
reverseLayout
)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
context,
attrs,
defStyleAttr,
defStyleRes
)
override fun smoothScrollToPosition(
recyclerView: RecyclerView,
state: RecyclerView.State,
position: Int
) {
val centerSmoothScroller = CenterSmoothScroller(recyclerView.context)
centerSmoothScroller.targetPosition = position
startSmoothScroll(centerSmoothScroller)
}
private class CenterSmoothScroller(context: Context) : LinearSmoothScroller(context) {
override fun calculateDtToFit(
viewStart: Int,
viewEnd: Int,
boxStart: Int,
boxEnd: Int,
snapPreference: Int
): Int = (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2)
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi
}
}
companion object {
// This number controls the speed of smooth scroll
private const val MILLISECONDS_PER_INCH = 150f
}
}
Uso:
recyclerView.layoutManager = CenterLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
recyclerView.smoothScrollToPosition(selectedPosition)
desde ahora (febrero de 2019), podría usar fácilmente este código en ListView
(ListView)word_list_view.smoothScrollToPositionFromTop(your_item_index, center_position.y);
RecyclerView no verificado, supongo que sería lo mismo.
-
No disponible para RecyclerView
– tagy22
18 de diciembre de 2019 a las 13:42
-
No disponible para RecyclerView
– tagy22
18 de diciembre de 2019 a las 13:42