如何优化滞后的 JetPack Compose 布局

Jer*_*emi 5 performance android lag android-jetpack-compose

我正在使用HorizontalPager来自伴奏者的包。寻呼机将为用户存储的每个练习提供一页。

寻呼机中的每个页面都有一个,其中包含多个带有s 和 等LazyColumn控件的卡片。卡的数量取决于用户配置的套数。我预计典型的数字在 1 到 8 之间,但在任何给定时间屏幕上只能看到 3 到 5 个(取决于屏幕尺寸和分辨率)。IconButtonBasicTextField

问题是,每次HorizontalPager需要构建包含 3 张以上卡片的新页面时,此布局都会产生明显的滞后(动画跳帧)。在页面之间交换时会发生这种情况。在真实设备(Galaxy S10e)和模拟器上运行的调试和发布版本中也会发生同样的情况。

我正在尝试优化此布局,因此无论屏幕上显示的卡片数量如何,每个帧的渲染时间都不超过 16 毫秒。

我之前曾尝试通过为某些可组合项设置固定高度来解决此问题,但这并没有多大帮助。我也尝试过使用Text而不是,然后当用户点击文本时,BasicTextField它会被替换为,但这并没有多大帮助,因此我删除了这个实现。BasicTextField

您对如何提高此布局的性能以消除延迟有什么建议吗?

下面是我的代码、应用程序屏幕和分析器的屏幕截图:

@ExperimentalPagerApi
@Composable
fun WorkoutSessionScreen(
    navHostController: NavHostController,
) {
    val pagerState = rememberPagerState()

    Scaffold(
        topBar = { MyTopAppBar(navHostController = navHostController) }
    ) {
        Box(
            modifier = Modifier
                .fillMaxHeight()
                .fillMaxWidth()
                .background(MaterialTheme.colors.background)
                .imePadding()
        ) {
            HorizontalPager(
                count = 10, state =
                pagerState,
                itemSpacing = 16.dp
            ) {
                Log.e("==>", "Building horizontal pager")
                TrackingControls()
            }

            Box(
                modifier = Modifier
                    .height(70.dp)
                    .fillMaxWidth()
                    .background(Color(0xFAF7F7FF))
                    .align(Alignment.BottomCenter)
            ) {
                Column(
                    Modifier.fillMaxWidth()
                ) {
                    Divider(color = Color(0x2A5C5C5C))
                    BottomControls()
                }
            }
        }
    }
}

@Composable
private fun TrackingControls() {

    LazyColumn(
        Modifier
            .fillMaxHeight()
            .fillMaxWidth(),
        contentPadding = PaddingValues(vertical = 8.dp)
    ) {
        items(6) { item ->
            SetsAndRepsTrackingControls(
                modifier = Modifier
            )
        }
    }
}

@Composable
private fun BottomControls() {
    Text(text = "Bottom Controlls")
}
Run Code Online (Sandbox Code Playgroud)
@Composable
fun SetsAndRepsTrackingControls(modifier: Modifier = Modifier) {
    val add = painterResource(id = R.drawable.ic_round_add_24)
    val remove = painterResource(id = R.drawable.ic_round_remove_24)


    Card(
        modifier
            .fillMaxWidth()
            .height(200.dp)
            .padding(vertical = 16.dp, horizontal = 8.dp),
        backgroundColor = MaterialTheme.colors.surface,
        shape = RoundedCornerShape(12.dp),
    ) {
        Column() {
            ControlsHeader()
            TrackingInput(label = "REPS", add, remove)
            Divider(color = Color.LightGray)
            TrackingInput(label = "WEIGHT (KG)", add, remove)
        }
    }
}

@Composable
private fun ControlsHeader() {
    Row(
        modifier = Modifier
            .height(56.dp)
            .fillMaxWidth()
            .background(MaterialTheme.colors.primary, RoundedCornerShape(12.dp))
            .padding(horizontal = 16.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text(text = "Set 1")
        Text(text = "CheckBox")
    }
}

@Composable
private fun TrackingInput(label: String = "Preview", add: Painter, remove: Painter) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(60.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        IconButton(onClick = {}) {
            Icon(
                painter = painterResource(id = R.drawable.ic_round_remove_24),
                contentDescription = "Minus",
                tint = MaterialTheme.colors.onSurface
            )
        }

        Column(
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            BasicTextField(
                singleLine = true,
                value = "8",
                onValueChange = {},
                textStyle = TextStyle(
                    textAlign = TextAlign.Center,
                    color = MaterialTheme.colors.onSurface
                ),
            )
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                text = label,
                style = MaterialTheme.typography.overline.copy(color = MaterialTheme.colors.onSurface)
            )
        }

        IconButton(onClick = { Log.d("==>", "tada") }) {
            Icon(
                painter = painterResource(id = R.drawable.ic_round_add_24),
                contentDescription = "Minus",
                tint = MaterialTheme.colors.onSurface
            )
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

申请打印屏幕

此分析器打印屏幕显示了名为 SetsAndRepsTrackingControls 的单个卡的渲染

分析器