20230911
MoMo Lv5

New

收藏列表跳转到播放后返回定位到当前播放的位置

记录当前播放是第几个视频

attachFirstVisibleViewHolder中拿到当前播放的position,通过attachPlayer播放视频,在这里传入position参数到VideoFlowViewModel

1
2
3
4
5
6
7
8
9
val position = layoutManager.findFirstCompletelyVisibleItemPosition()
if (position == RecyclerView.NO_POSITION) return
...
delegate.attachPlayer(
surface,
clip,
positionResponder = viewHolder,
position
)
1
2
3
4
5
6
7
8
9
10
11
12
13
override fun attachPlayer(
surface: Surface,
clip: Clip,
positionResponder: ClipPositionResponder?,
position: Int
) {
this@VideoFlowViewModel.attachPlayer(
surface,
clip,
positionResponder = positionResponder,
position = position
)
}

attachPlayersetPlayerClipDatasource用来播放视频,在这个方法中更新position

1
2
// 更新当前播放的视频下标
setCurrentClipPosition(position)

VideoFlowViewModel中通过静态方法更新参数

1
2
3
private var currentClipPosition: Int = -1
fun setCurrentClipPosition(position: Int) { currentClipPosition = position }
fun getCurrentClipPosition(): Int { return currentClipPosition }

拿到最新的视频下标

FavoriteFragment

position是视频的位置,收藏列表中还包括了日期,要通过position计算出包括日期的下标

1
2
3
4
// 当前浏览过的视频的下标
val position = VideoFlowViewModel.getCurrentClipPosition()
// 包括date的下标
val positionNew = viewModel.searchResultAdapter.countDateBeforeClip(position)

FavoriteAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 通过单独clip的位置返回包括date的位置
* */
fun countDateBeforeClip(clipPosition: Int): Int {
var count = 0
var clipCount = 0

for (item in itemList) {
if (item is String) count += 1
else clipCount += 1
if (clipCount == clipPosition + 1) break
}
return count + clipPosition
}

滚动到指定位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
if (positionNew > 0) {
if (recyclerView.layoutManager == null || recyclerView.adapter == null) {
logger.d(TAG, "RecyclerView layout or adapter is not set")
return
}

// 滚动位置是否在可见范围内
val lastVisiblePosition = layoutManager.findLastVisibleItemPosition()
val rowHeight = if (positionNew < lastVisiblePosition) {
layoutManager.findViewByPosition(positionNew)?.bottom
} else {
resources.displayMetrics.heightPixels
}

/**
* 滚动到最后播放的clip可见位置,再整体移到顶部
* 24 safe_area_top_guide
* 48 导航栏
* 16 recyclerView margin-top
* 96 视频高度
* 4 clip padding-top
* */
recyclerView.scrollToPosition(positionNew)
val scrollDistance = MeasureUtil.dp2px(context, 24f + 48f + 16f + 96f + 4f)
logger.d(TAG, "onResume height: $rowHeight padding $scrollDistance")

if (rowHeight != null) {
binding.recyclerView.smoothScrollBy(0, rowHeight - scrollDistance)
}
}

Bug

由于所有的视频播放都共用一个adapter,存在首页或者搜索页向下刷视频的时候位置会不断更新,导致首次进入收藏页也会导致位置滚动,所以在第一次进入收藏的时候重置位置

1
2
3
4
5
6
7
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
VideoFlowViewModel.setCurrentClipPosition(DEFAULT_POSITION)
}
Powered by Hexo & Theme Keep
Unique Visitor Page View