仿抖音评论,点击回复自动将该条评论上移至第一条

打开抖音的评论,回复评论时,自动将该条评论上滑至最上方的位置,目的也是为了让用户能够回复的时候,看到他要回复评论的内容

评论有一级评论和二级评论,一级评论是评论弹窗下的recyclerView,二级评论又是一级评论adpter中某一个item的一个recyclerView,回复一级评论时,上移相对简单一点,如果回复二级评论时,把二级评论上移到第一条稍微复杂一些。

有2种方法,目测抖音的评论就是用的一种方法

方法实现原理:先计算出该评论的在整个屏幕中的位置,主要是point Y这个点,然后计算移动到第一条需要向上移动的距离,通过属性动画完成。

具体步骤看代码注释

Kotlin 复制代码
// 1. 拿到一级评论对应的viewHolder,有了这个viewHolder就可以拿到指定的子view
val viewHolder1 =
    viewHolder!!.rvList.findViewHolderForAdapterPosition(mFirstCommentPosition)
if (viewHolder1 != null && viewHolder1 is VideoDetailCommentAdapter.VideoDetailCommentViewHolder) {
    val viewHolder2 = viewHolder1 as VideoDetailCommentAdapter.VideoDetailCommentViewHolder
    val location = IntArray(2)
    // 如果回复一级评论,默认mSecondCommentPosition为-1,如果回复二级评论,mSecondCommentPosition肯定就不是-1了,因为position是从0开始的
    if (mSecondCommentPosition != -1) {
    // 拿到二级评论的viewHolder
        val viewHolder3 = viewHolder2.rvList.findViewHolderForAdapterPosition(mSecondCommentPosition)
        if (viewHolder3 != null && viewHolder3 is VideoDetailSecondCommentAdapter.VideoDetailSecondCommentViewHolder) {
            val viewHolder4 = viewHolder3 as VideoDetailSecondCommentAdapter.VideoDetailSecondCommentViewHolder
            // 我获取的时该评论头像相对于屏幕的的具体的点,用的是getLocationOnScreen,当然也可以参考使用# getLocationInWindow
            viewHolder4.rrivAvatar.getLocationOnScreen(location)
            // 获取需要上移的距离,然后上移
            translateY = (location[1] - AppUtil.dp2px(264f)) * -1.0f
            val ani: ObjectAnimator = ObjectAnimator.ofFloat(viewHolder!!.rvList, "translationY", 0f, translateY)
            ani.duration = 300
            ani.start()
        }
    } else {
        // 我获取的时该评论头像相对于屏幕的的具体的点,用的是getLocationOnScreen,当然也可以参考使用# getLocationInWindow
        viewHolder2.rrivAvatar.getLocationOnScreen(location)
        // 获取需要上移的距离,然后上移
        translateY = (location[1] - AppUtil.dp2px(264f)) * -1.0f
        val ani: ObjectAnimator = ObjectAnimator.ofFloat(viewHolder!!.rvList, "translationY", 0f, translateY)
        ani.duration = 300
        ani.start()
    }
}

方法二,通过scrollToPositionWithOffset实现

scss 复制代码
linearLayout.scrollToPositionWithOffset(mFirstCommentPosition, translateY)

其中mFirstCommentPosition为一级评论的position,translateY为二级评论相对于一级评论的在竖直方向上的高度。

该方法有个小问题,不能实现缓慢的滑动效果,直接就上去了,有点突兀。

当然还有一个方法,调用recyclerView的smoothScrollToPosition方法,该方法只能实现评论滑动到屏幕可见,一般是在最下方,并不能实现滑动到顶。scrollToPositionWithOffset方法的第2个参数如果设置为0就可以实现滑动到顶。

还有一个小问题,就是如果回复的评论恰好是最后一条,则滑不上去了,因为下方没有数据了。

具体代码如下

ini 复制代码
val linearLayout = viewHolder!!.rvList.layoutManager as LinearLayoutManager

val viewHolder1 =
    viewHolder!!.rvList.findViewHolderForAdapterPosition(mFirstCommentPosition)
if (viewHolder1 != null && viewHolder1 is VideoDetailCommentAdapter.VideoDetailCommentViewHolder) {
    val viewHolder2 = viewHolder1 as VideoDetailCommentAdapter.VideoDetailCommentViewHolder
    val location = IntArray(2)
    viewHolder2.rrivAvatar.getLocationOnScreen(location)
    if (mSecondCommentPosition != -1) {
        val viewHolder3 = viewHolder2.rvList.findViewHolderForAdapterPosition(mSecondCommentPosition)
        if (viewHolder3 != null && viewHolder3 is VideoDetailSecondCommentAdapter.VideoDetailSecondCommentViewHolder) {
            val viewHolder4 = viewHolder3 as VideoDetailSecondCommentAdapter.VideoDetailSecondCommentViewHolder
            val location1 = IntArray(2)
            viewHolder4.rrivAvatar.getLocationOnScreen(location1)
            translateY = (location1[1] - location[1]) * -1
            linearLayout.scrollToPositionWithOffset(mFirstCommentPosition, translateY)
        }
    } else {
        linearLayout.scrollToPositionWithOffset(mFirstCommentPosition, 0)
    }
}
相关推荐
千码君20169 分钟前
个人开发者:安卓手机adb调试
android·adb·智能手机
我不会插花弄玉11 小时前
7.函数【由浅入深-MySQL】
android·数据库·mysql
vilya12 小时前
手机端 Agent 怎么动起来:Kotlin 与 Python 之间的桥
android·agent
高晶12 小时前
Android 新手实战:从零搭建 WebRTC 在线直播系统
android·程序员
alexhilton12 小时前
为什么你的 LazyColumn 仍然卡顿
android·kotlin·android jetpack
>Andre<13 小时前
系统架构全景
android
hai_android18 小时前
Android 嵌套滑动冲突:内部拦截 vs 外部拦截实战
android·android studio·android jetpack
木子欢儿19 小时前
Zabbix 7.4 Alpine 版 Docker Compose 部署
android·运维·docker·容器·zabbix
素师良码20 小时前
第9篇:Android驱动踩坑实录:DSI RX FIFO前置脏0、数据错位复盘
android
夜雪一千21 小时前
如何在MySQL中实现字段级加密
android·数据库·mysql