20:26:44.466 D onBindViewHolder end duration:5 ms 20:26:44.466 D onCreateViewHolder start 20:26:44.476 D inflateAndInit=9 ms 20:26:44.476 D onCreateViewHolder end 20:26:44.476 D onBindViewHolder start 20:26:44.478 D bind ... 20:26:46.194 D onBindViewHolder end duration:2 ms 20:26:46.194 D onCreateViewHolder start 20:26:46.202 D inflateAndInit=7 ms 20:26:46.202 D onCreateViewHolder end 20:26:46.202 D onBindViewHolder start 20:26:46.204 D bind 20:26:46.388 I Davey! duration=2310ms; Flags=1, IntendedVsync=468755453549798, Vsync=468755694290532, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=468755696759855, AnimationStart=468755696769480, PerformTraversalsStart=468755698176189, DrawStart=468757624058091, SyncQueued=468757755773604, SyncStart=468757756304437, IssueDrawCommandsStart=468757759398438, SwapBuffers=468757762351855, FrameCompleted=468757764867772, DequeueBufferDuration=473084, QueueBufferDuration=946750, GpuCompleted=0,
原理加载时逐步渲染ViewHolders,RecycleView本身是一次性创建全部onBindViewHolder,那我们就分多次提交信息!
实际上我完全没有优化加载,只是及时的去渲染,这样我们就不会跳帧2310ms了!
viewModel.timeCells.observe(viewLifecycleOwner) { cells ->
submitGradually(meetingTimeGridAdapter, cells, firstBatch = 2, chunk = 2)
}
@Suppress("SameParameterValue")
private fun <T> submitGradually(
adapter: ListAdapter<T, *>,
all: List<T>,
firstBatch: Int,
chunk: Int
) {
val size = all.size
var upto = minOf(firstBatch, size)
adapter.submitList(all.subList(0, upto).toList()) {
val choreographer = Choreographer.getInstance()
val cb = object : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
if (upto >= size) return
val next = minOf(upto + chunk, size)
// 必须传新列表对象
adapter.submitList(all.subList(0, next).toList()) {
upto = next
if (upto < size) choreographer.postFrameCallback(this)
}
}
}
choreographer.postFrameCallback(cb)
}
}