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

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

评论有一级评论和二级评论,一级评论是评论弹窗下的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)
    }
}
相关推荐
zhu620197627 分钟前
Android10如何设置ro.debuggable=1?
android·安全·android逆向·android10·ro.debuggable
androidwork1 小时前
Android 内存溢出(OOM)的 Kotlin 排查与优化指南
android·开发语言·kotlin
xzkyd outpaper1 小时前
Android中PID与UID的区别和联系
android·计算机八股
Developings1 小时前
Android logcat命令汇总
android
吃着火锅x唱着歌2 小时前
PHP7内核剖析 学习笔记 第八章 命名空间
android·笔记·学习
君的名字2 小时前
怎么判断一个Android APP使用了React Native 这个跨端框架
android·react native·react.js
君的名字3 小时前
怎么判断一个Android APP使用了Electron 这个跨端框架
android·javascript·electron
君的名字4 小时前
怎么判断一个Android APP使用了Qt 这个跨端框架
android·开发语言·qt
xzkyd outpaper6 小时前
Android中Framework用到了哪些跨进程通信方式
android·计算机八股
珹洺6 小时前
计算机操作系统(十二)详细讲解调计算机操作系统调度算法与多处理机调度
android·java·数据库