[英]RecyclerView smoothScroll to position in the center. android
I am using a horizontal layout manager for my RecyclerView
.我正在为我的
RecyclerView
使用水平布局管理器。 I need to make RecyclerView
in the next way: when click on some item - make smoothScrool to that position and put that item in the center of RecyclerView
(if it possible, for example, 10 item from 20).我需要以下一种方式制作
RecyclerView
:当单击某个项目时 - 使 smoothScool 到该位置并将该项目放在RecyclerView
的中心(如果可能,例如,20 中的 10 个项目)。
So, I have no problem with smoothScrollToPosition()
, but how to put item than in the center of RecyclerView
???所以,我对
smoothScrollToPosition()
没有问题,但是如何将 item 放在RecyclerView
的中心?
Thanks!谢谢!
Yes it's possible.是的,这是可能的。
By implementing RecyclerView.SmoothScroller
's method onTargetFound(View, State, Action)
.通过实现
RecyclerView.SmoothScroller
的方法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);
Specifically in LinearLayoutManager
with LinearSmoothScroller
:特别是在带有
LinearSmoothScroller
LinearLayoutManager
:
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);
}
}
}
Improvements to the answer - there is no need to override the LinearLayoutManager
答案的改进 -无需覆盖
LinearLayoutManager
From the previous answer:从上一个答案:
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);
}
}
Here how to use it:这里如何使用它:
RecyclerView.LayoutManager lm = new GridLayoutManager(...): // or whatever layout manager you need
...
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
lm.startSmoothScroll(smoothScroller);
Just in case someone needs the Kotlin equivalent of the class in the accepted answer.以防万一有人需要在接受的答案中与该课程等效的Kotlin 。
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)
}
}
I am using a horizontal layout manager for my RecyclerView
.我正在为
RecyclerView
使用水平布局管理器。 I need to make RecyclerView
in the next way: when click on some item - make smoothScrool to that position and put that item in the center of RecyclerView
(if it possible, for example, 10 item from 20).我需要以另一种方式制作
RecyclerView
:单击某个项目时-将smoothScrool放置到该位置,然后将该项目放在RecyclerView
的中心(如果可能,例如20个项目中的10个)。
So, I have no problem with smoothScrollToPosition()
, but how to put item than in the center of RecyclerView
???因此,我对
smoothScrollToPosition()
没问题,但是如何将项目放在RecyclerView
的中心?
Thanks!谢谢!
Based on @Boda's answer, if you want to control smooth scroll speed (for better animation) you can use below:根据@Boda 的回答,如果您想控制平滑滚动速度(以获得更好的动画效果),您可以使用以下方法:
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
}
}
Usage:用法:
recyclerView.layoutManager = CenterLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
recyclerView.smoothScrollToPosition(selectedPosition)
since now(Feb 2019), I could easily use this code in ListView从现在(2019 年 2 月)开始,我可以轻松地在 ListView 中使用此代码
(ListView)word_list_view.smoothScrollToPositionFromTop(your_item_index, center_position.y);
RecyclerView not verified, I guess would be the same. RecyclerView 未验证,我想应该是一样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.