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

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

评论有一级评论和二级评论,一级评论是评论弹窗下的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)
    }
}
相关推荐
移动开发者1号1 小时前
ReLinker优化So库加载指南
android·kotlin
山野万里__1 小时前
C++与Java内存共享技术:跨平台与跨语言实现指南
android·java·c++·笔记
Huckings1 小时前
Android 性能问题
android
移动开发者1号2 小时前
剖析 Systrace:定位 UI 线程阻塞的终极指南
android·kotlin
移动开发者1号2 小时前
深入解析内存抖动:定位与修复实战(Kotlin版)
android·kotlin
whysqwhw2 小时前
OkHttp深度架构缺陷分析与革命性演进方案
android
Digitally4 小时前
如何将文件从 iPhone 传输到 Android(新指南)
android·ios·iphone
whysqwhw5 小时前
OkHttp深度架构缺陷分析与演进规划
android
用户7093722538515 小时前
Android14 SystemUI NotificationShadeWindowView 加载显示过程
android
木叶丸5 小时前
跨平台方案该如何选择?
android·前端·ios