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

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

评论有一级评论和二级评论,一级评论是评论弹窗下的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)
    }
}
相关推荐
我命由我123453 分钟前
Android 开发 - 关于 startActivity 后立刻 finish、requestWindowFeature 方法注意事项
android·java·开发语言·java-ee·kotlin·android studio·android-studio
PyHaVolask8 分钟前
安全编码实战示例
android·安全·web安全代码
氦客8 小时前
Android Compose : 传统View在Compose组件中的等价物
android·compose·jetpack·对比·传统view·等价物·compose组件
神话20099 小时前
Rust 初体验与快速上手指南
android·rust
CheungChunChiu9 小时前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
aidou131411 小时前
Android中设置Dialog和自定义布局相同高度
android·dialog·弹窗高度·getwindow
氦客11 小时前
UI编程的发展史 : 结合命令式UI和声明式UI
android·compose·声明式ui·ui编程·命令式ui·ui编程发展史·标记语言
aidou131413 小时前
Android中RecyclerView实现多级列表
android·recyclerview·多级列表·layoutmanager
青风行13 小时前
Android从入门到进阶
android
方白羽14 小时前
Android 开发中,准确判断应用处于“前台(Foreground)”还是“后台(Background)
android·app·客户端