以前实现RecyclerView滑动到具体position是通过《RecyclerView定位到具体position》这篇文章中的方法来实现。
这种方法不是很优雅,因为如果要定位的position在最后一个可见项之后,就会出现滑动一下再滑动一下的现象,不是很连贯。
下面介绍一种更优雅的实现方式。
这种方案是通过SDK提供的LinearSmoothScroller来实现的。
val smoothScroller = object : LinearSmoothScroller(this) {
override fun getVerticalSnapPreference(): Int {
return LinearSmoothScroller.SNAP_TO_START
}
}
首先创建一个LinearSmoothScroller。重写getVerticalSnapPreference()返回SNAP_TO_START。
SNAP_TO_START的意思是指需要定位的position那个View的top和left和父布局(RecyclerView)的top和left对齐,也就是需要定位的position那个View出现在第一个可见位置。
同理,SNAP_TO_END的意思是指需要定位的position那个View出现在最后一个可见位置。
因为我们需要将position的View出现在第一个可见位置,所以getVerticalSnapPreference()方法我们返回SNAP_TO_START。
在需要跳转的地方,我们调用下面代码即可:
smoothScroller.targetPosition = position
recycler.layoutManager.startSmoothScroll(smoothScroller)
这种方案相比上面一种代码精简了不少,而且那种“滑动一下再滑动一下的现象”的现象也不存在。
如果觉得默认滑动速度比较突兀不够流畅的话,我们还可以将其的滑动速度调慢一点,让其滑动更平缓。重写LinearSmoothScroller的calculateSpeedPerPixel方法即可。
val smoothScroller = object : LinearSmoothScroller(this) {
override fun getVerticalSnapPreference(): Int {
return LinearSmoothScroller.SNAP_TO_START
}
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
return 40F / displayMetrics.densityDpi
}
}
calculateSpeedPerPixel的方法返回值是滑动每个像素所需要的时间(毫秒),默认是25F / displayMetrics.densityDpi。如果需要调慢一点可将这个值调大一点。可以根据实际体验,设置一个合适的值。