【Android】RecycleView 将指定item滚动置顶(kotlin)

这篇具有很好参考价值的文章主要介绍了【Android】RecycleView 将指定item滚动置顶(kotlin)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、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 即可。

三、完整代码

// 需要置顶的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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python使用PyQt5实现指定窗口置顶

    工作中,同事随口提了一句:要是能让WPS窗口置顶就好了,老是将窗口切换来切换去的太麻烦了。 然后,这个奇怪的点子引起了本人的注意,那就试试能不能实现吧。 不知道是不是我手法或版本的缘故,用了网上找的代码都是窗口弹出而已,并没有把它置顶,可以参考以下

    2024年02月13日
    浏览(57)
  • Android Studio安卓开发-RecycleView新闻栏设计

    在上一博客中,我们完成类微信UI开发,在此基础上,在联系人界面实现RecycleView的简单用例,在发现界面实现RecycleView的流式布局。如下图所示。 对于RecycleView的基础布局学习我们先到这,现在需要我们对每一个RecycleView的Item实现点击操作,能够跳转至Item的详情界面,下面我

    2024年02月16日
    浏览(43)
  • QTableView只有一列item的水平横向滚动条scrollbar设置方法

    若只有一列item则需 先设置ui.tableView_alarm-setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); 再ui.tableView_alarm-setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); HorizontalScrollBarPolicy设置为needed和alwayson均可,不要设置成off 如果在tabwidget下的多个tab下添加tableview,可以通过同时设置最小列宽和自

    2023年04月08日
    浏览(34)
  • uniapp设置滚动条滚动到指定位置

    场景:左侧菜单栏,每次切换时,需要右侧商品展示区保持滚动条及页面在最顶部   scrollToTop在0,1之间切换,通过1px的差别使页面可以正常渲染 1) 使用 uni.pageScrollTo 方法,属于页面级别滚动。 如果传入 scrollTop 不起效,应该是布局的问题, 它是页面级的滚动: 所有的

    2024年02月09日
    浏览(80)
  • Android自定义侧滑Item

    源码地址:https://github.com/LanSeLianMa/CustomizeView/tree/master/cehuaitem 先定义一个容器

    2024年02月13日
    浏览(46)
  • Android:RecyclerView自由拖动item

    原生就自带有可拖动item的工具:ItemTouchHelper 看下效果: 可拖动RecyclerView预览效果 接下来我们看如何使用。 其中判断条件中的item.isMovable这边是记录该item是否可以拖动,也可以换成其他判断条件比如根据位置判断等。 另外,需要留意一点,如果你是在onBindViewHolder中有设置点

    2024年01月23日
    浏览(48)
  • Android Recyclerview的item间距实现

    Recyclerview中,提供了一个方法 addItemDecoration 给我们用于设置item的分割线 下面提供几个常见的分割线效果 注: 下面的 SizeUtils 是AndroidUtilCode此库里的工具类,需要添加依赖,也可以自行修改封装的方法(主要是将dp单位转为px) 以下代码已封装在我的库中stars-one/XAndroidUtil: 封装自己常

    2024年02月05日
    浏览(61)
  • 小程序页面滚动到指定位置

    如何让页面自动滚动到某个位置(比如点击某一个按钮,需要自动滚动到对应内容的位置),在小程序是很简单的,官方提供获取元素位置和滚动到目标位置API: 1.使用uni.createSelectorQuery().select().boundingClientRect()查询到需要滚动到的元素位置 2.滚动到目标位置: uni.pageScrollTo() 微

    2024年02月12日
    浏览(33)
  • uniapp 滚动页面到指定位置

    小程序业务中,通常会有用户点击某个按钮或者tab标签,然后页面滚动到相连内容位置 this.scrollTop = res.top;  这么写是因为我用了scroll-view   一般写法

    2024年02月12日
    浏览(41)
  • Android LinearLayout快速设置每个item间隔

    原文地址: Android LinearLayout快速设置每个item间隔 平常使用LinearLayout的时候,有时候会需要对每个item设置间距,但是每个item都加上margin的方法实在有些繁琐 因为之前是在写JavaFx程序,里面的Vbox或Hbox都会提供一个Space的参数,可以用来快速设置每个item之间的间距 而Android这边,是没看

    2024年02月17日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包