![](/img/trans.png)
[英]How do layouts work in Jetpack Compose and how do they relate to XML?
[英]How to do work off the main thread in Jetpack Compose?
在 Jetpack Compose 应用程序中,我有一个 LazyVerticalGrid 缩略图,每个缩略图都需要在撰写时绘制在位图支持的 Canvas 中。
如果我只是在 Canvas 的 DrawScope 中绘制缩略图,则可以正确绘制缩略图,但用户体验很差。 当用户滚动 LazyVerticalGrid 时,每个缩略图都会自行绘制,因此会出现很多卡顿现象。
我原以为 Jetpack Compose 在需要时在后台线程中组合,但这一切似乎都发生在主线程上,导致严重的卡顿,即使在最新的手机上也是如此。
我可以通过使用 LaunchedEffect withContext(IO) 在另一个线程上绘制到 Canvas 的底层位图来解决卡顿问题。 但问题是,Compose 不知道在绘制位图时重新组合 Canvas,所以我经常以半绘制的缩略图结束。
有没有一种方法可以在主线程之外完成工作,然后在完成工作后重新组合?
这是卡住的代码(为简洁起见进行了编辑),然后是在绘图完成后并不总是重新组合的非卡住版本:
val imageBitmap = remember {Bitmap.createBitmap(515, 618, Bitmap.Config.ARGB_8888)}
val bitmapCanvas = remember { android.graphics.Canvas(imageBitmap) }
ElevatedCard() {
Canvas() {
bitmapCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
penStrokes.forEach {
inker.drawEvent(it)
}
this.drawImage(imageBitmap.asImageBitmap())
}
}
非简陋但仍然不正确
val imageBitmap = remember {Bitmap.createBitmap(515, 618, Bitmap.Config.ARGB_8888)}
val bitmapCanvas = remember { android.graphics.Canvas(imageBitmap) }
LaunchedEffect(Unit) {
withContext(IO) {
bitmapCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
penStrokes.forEach {
inker.drawEvent(it)
}
}
}
ElevatedCard() {
Canvas() {
this.drawImage(imageBitmap.asImageBitmap())
}
}
最后,我使用了人们似乎用来强制 Jetpack Compose 根据命令重绘的常见“invalidate++”kludge。 我认为它有一点代码味道,但它确实有效。
val imageBitmap = remember {Bitmap.createBitmap(515, 618,
Bitmap.Config.ARGB_8888)}
val bitmapCanvas = remember { android.graphics.Canvas(imageBitmap) }
var invalidate by remember { mutableStateOf(0) }
LaunchedEffect(Unit) {
withContext(IO) {
bitmapCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
penStrokes.forEach {
inker.drawEvent(it)
}
invalidate++
}
}
ElevatedCard() {
Canvas() {
invalidate.let {
this.drawImage(imageBitmap.asImageBitmap())
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.