打开抖音的评论,回复评论时,自动将该条评论上滑至最上方的位置,目的也是为了让用户能够回复的时候,看到他要回复评论的内容
评论有一级评论和二级评论,一级评论是评论弹窗下的recyclerView,二级评论又是一级评论adpter中某一个item的一个recyclerView,回复一级评论时,上移相对简单一点,如果回复二级评论时,把二级评论上移到第一条稍微复杂一些。
有2种方法,目测抖音的评论就是用的一种方法
方法实现原理:先计算出该评论的在整个屏幕中的位置,主要是point Y这个点,然后计算移动到第一条需要向上移动的距离,通过属性动画完成。
具体步骤看代码注释
// 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实现
linearLayout.scrollToPositionWithOffset(mFirstCommentPosition, translateY)
其中mFirstCommentPosition为一级评论的position,translateY为二级评论相对于一级评论的在竖直方向上的高度。
该方法有个小问题,不能实现缓慢的滑动效果,直接就上去了,有点突兀。
当然还有一个方法,调用recyclerView的smoothScrollToPosition方法,该方法只能实现评论滑动到屏幕可见,一般是在最下方,并不能实现滑动到顶。scrollToPositionWithOffset方法的第2个参数如果设置为0就可以实现滑动到顶。
还有一个小问题,就是如果回复的评论恰好是最后一条,则滑不上去了,因为下方没有数据了。
具体代码如下
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)
}
}