android - Jetpack Compose:当带有 GlideImage 的元素在 LazyColumn 中可点击时出现性能问题
问题描述
我有带有 LazyColumn 的 VideoListScreen,我使用 VideoItem 作为我的项目。这个 LazyColumn 它是使用网格项创建的,具有带有类别标题的惰性网格视图。标签是类别的标签。类别详细信息是有关类别颜色、标题等的信息:
@Composable
fun VideoItem(
videoPath: String,
brush: Brush,
modifier: Modifier = Modifier,
onClick: () -> Unit
) {
val assetFileDescriptor = LocalContext.current.assets.open(videoPath)
Surface(
modifier = modifier
.padding(5.dp)
.aspectRatio(1f)
.clickable { onClick() },
shape = Shapes.small,
elevation = 1.dp
) {
GlideImage(
imageModel = assetFileDescriptor.readBytes(),
contentScale = ContentScale.Crop,
requestOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE),
shimmerParams = ShimmerParams(
baseColor = MaterialTheme.colors.background,
highlightColor = Blue200,
durationMillis = 650,
dropOff = 0.65f,
tilt = 20f
)
)
Box(modifier = Modifier
.background(brush)
.fillMaxSize() )
}
}
视频列表屏幕:
@Composable
fun VideoListScreen(
navController: NavHostController,
tag: String
) {
val cells = 2
val context = LocalContext.current
val categoryDetails = getCategoryDetailsBy(tag)
val videos = fetchVideos(context, tag)
LazyColumn(contentPadding = PaddingValues(5.dp)) {
item {
CategoryElement(
categoryDetails = categoryDetails,
modifier = Modifier
.fillMaxWidth()
.height(130.dp)
.padding(5.dp),
customTitle = "O kategorii"
)
}
gridItems(videos, cells) { assetFileName ->
val videoPath = "$tag/$assetFileName"
VideoItem(
videoPath = videoPath,
brush = categoryDetails.transparentBrush
) { navController.navigateToPlayer(videoPath) } //onClick function
}
}
}
private fun fetchVideos(context: Context, tag: String): List<String> {
return context.resources.assets.list("$tag/")?.toList() ?: listOf()
}
gridItems 扩展功能:
fun <T> LazyListScope.gridItems(
data: List<T>,
cells: Int,
itemContent: @Composable BoxScope.(T) -> Unit,
) {
items(data.chunked(cells)) { row ->
Row(Modifier.fillMaxWidth()) {
for ((index, item) in row.withIndex()) {
Box(Modifier.fillMaxWidth(1f / (cells - index))) {
itemContent.invoke(this, item)
}
}
}
}
}
问题是,当我尝试在此项目上应用可点击性时(无论在哪里),缩略图加载(从资产)变得几乎两倍慢。当 onClick 函数为空时,有趣的是,性能问题消失了。在名为“navigateToPlayer(videoPath)”的函数中,我导航到另一个屏幕并使用 navController 发送“videoPath”。
如果您有任何问题随时问!
解决方案
在 compose 中,您正在使用视图构建器创建 UI。这个函数可以多次调用,当你开始使用动画时,它甚至可以在每一帧上重新组合。
这就是为什么你不应该直接在可组合函数中执行任何繁重的工作。如果你这样做了,你需要存储结果,这样你就不需要在下一次重组时重新计算。
两者fetchVideos
和assets.open
都是相当繁重的操作,甚至getCategoryDetailsBy
应该缓存(不确定那是什么)的结果。为此,您需要使用remember
or rememberSaveable
。看看这些有什么不同以及更多关于可组合物中的状态。
因此,像这样更新您的声明:
val categoryDetails = remember { getCategoryDetailsBy(tag) }
val videos = remember { fetchVideos(context, tag) }
val context = LocalContext.current
val assetFileDescriptor = remember { context.assets.open(videoPath) }
推荐阅读
- f# - 解析具有动态列数的尴尬 CSV 文件会出错
- shell - 命令不起作用
- android - 在 dialogFragment 中放置 viewModel 观察者的位置?
- python - IntelliSense 不适用于 Visual Studio Code/可嵌入 python
- javascript - 不变违规:未找到名称 p 的视图配置
- javascript - 在同一脚本中编写另一个函数后,javascript 函数停止工作
- html - 为什么“使用”标签大小与它引用的 svg 元素不匹配?
- javascript - 使用javascript的打字效果不起作用
- python - Python 示例并从列表中删除项目
- sql - 存储过程(输入与输出)与返回 - SQL Server