一、RecyclerView本身提供的定位方法说明
// 滑动到适配器指定位置(position:item的index)
smoothScrollToPosition(position)
// 使指定的item平滑滚动到屏幕中
// 说明:
// 情况1:指定item在可见范围外时,则滑动到可见范围
// 情况2:指定item在可见范围内时,则不会滑动
recycleview.smoothScrollToPosition();
二、实现思路
item有三种情况:
情况1:在可见范围之前
item在第一个可见item之前,直接用smoothScrollToPosition,则当该item移动到可见范围时,它就在RecyclerView顶部
情况2:在可见范围内
tem在可见范围内(即在第一个可见item之后,最后一个可见item之前),这时scrollToPosition失效,需要手动计算该item的view距离顶部的距离,用scrollBy自行移动到置顶位置
情况3:在可见范围之后
item在最后一个可见item之后,有两种处理方式:
方式一:(不推荐,如item内容过长会有问题)
用smoothScrollToPosition滑动到可见范围 (此时该item在最后一个位置),再获取该item的view,计算到顶部距离,再监听RecyclerView的滑动,对其进行二次滑动到顶部
//标记是否需要二次滑动
var shouldMove: Boolean = false
// 监听RecyclerView的滑动,对需要进行二次滑动的item进行滑动
mRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (shouldMove && RecyclerView.SCROLL_STATE_IDLE == newState) {
shouldMove = false
smoothMoveToPosition(mRecyclerView, mPosition)
}
}
})
// smoothMoveToPosition函数内第三种情况代码替换为
recyclerView.smoothScrollToPosition(position)
mPosition = position
shouldMove = true
方式二:(推荐)
用smoothScrollToPosition滑动到可见范围,RecyclerView在用smoothScrollToPosition函数时,是创建了一个LinearSmoothScroller,其中有个 SNAP_TO_START参数 能将 子view与父view左对齐或顶部对齐,根据 LayoutManager 是 horizontal 还是 vertical 决定的,因此重写 LinearSmoothScroller,设置该参数即可实现置顶,之后在需要使用的地方获取 RecyclerView 的 LayoutManager ,调用 startSmoothScroll 即可。文章来源:https://www.toymoban.com/news/detail-764975.html
三、完整代码
// 需要置顶的item的index
var mPosition: Int = 0
//标记 当前可见item与顶部的距离是否为0:false则点击上一题时显示当前item
var shouldMove: Boolean = true
// 监听RecyclerView的滑动,当前可见item是否置顶
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (RecyclerView.SCROLL_STATE_IDLE == newState) {
mPosition = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(0))
if (recyclerView.childCount>0) {
// 计算当前可见item到顶部的距离
val top = recyclerView.getChildAt(0).top
// 手动滑动到顶部
shouldMove = top >= 0
}
}
}
})
// 让指定item置顶
fun smoothMoveToPosition(recyclerView: RecyclerView, position: Int) {
// 获取RecyclerView的第一个可见位置
val firstItem = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(0))
// 获取RecyclerView的最后一个可见位置
val lastItem = recyclerView.getChildLayoutPosition(recyclerView.getChildAt(recyclerView.childCount - 1))
if (position < firstItem) {
// 在可见范围之前,就smoothScrollToPosition可以直接跳转
recyclerView.smoothScrollToPosition(position)
} else if (position <= lastItem) {
// 在可见范围内
val pos = position - firstItem
if (pos >= 0 && pos < recyclerView.childCount) {
// 计算指定item的view到顶部的距离
val top = recyclerView.getChildAt(pos).top
// 手动滑动到顶部
recyclerView.smoothScrollBy(0, top)
}
} else {
// 在可见范围之后
mPosition = position
// 用smoothScrollToPosition滑动到可见范围
// RecyclerView在用smoothScrollToPosition函数时,是创建了一个LinearSmoothScroller有个SNAP_TO_START参数
// SNAP_TO_START:将子view与父view左对齐或顶部对齐,根据LayoutManager是horizontal还是vertical决定,
// 因此重写LinearSmoothScroller,设置该参数即可实现置顶
class TopSmoothScroller(context: Context) : LinearSmoothScroller(context) {
override fun getHorizontalSnapPreference(): Int {
return SNAP_TO_START
}
override fun getVerticalSnapPreference(): Int {
return SNAP_TO_START
}
}
val mTopScroller = TopSmoothScroller(requireContext())// requireContext()用于获取与片段相关联的Context对象
mTopScroller.targetPosition = position
recyclerView.layoutManager?.startSmoothScroll(mTopScroller)
}
}
// 点击显示上一个item
preQue.addPreventDoubleClickListener {
if (mPosition > 0 && shouldMove) {
mPosition -= 1
smoothMoveToPosition(recyclerView, mPosition)
}else{
if (recyclerView.childCount>0) {
// 计算当前可见item到顶部的距离
val top = recyclerView.getChildAt(0).top
// 手动滑动到顶部
recyclerView.smoothScrollBy(0, top)
shouldMove = true
}
}
}
// 点击显示下一个item
nextQue.addPreventDoubleClickListener {
if (mPosition < exp.expTopic.size) {
mPosition += 1
smoothMoveToPosition(recyclerView, mPosition)
}
}
四、参考链接
java版本文章来源地址https://www.toymoban.com/news/detail-764975.html
到了这里,关于【Android】RecycleView 将指定item滚动置顶(kotlin)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!