You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中LazyColumn内嵌LazyVerticalGrid实现方案咨询

实现带缩略图的AnswerOption网格布局方案

解决思路

利用Compose中LazyColumn允许嵌套LazyVerticalGrid的特性,通过判断当前问题的选项是否包含带缩略图的条目,动态切换选项的展示布局:有缩略图时用网格展示,无缩略图时保持原列表布局,同时保留原有页面的其他结构。

修改后的完整代码

@Composable
fun AssessmentScreen(
    onClose: (String, String) -> Unit,
    relatedSubSkillIdsJson: String,
    uiState: AssessmentUiState,
    onSelectedOption: (String) -> Unit,
    onShowAnswerFeedback: (Boolean) -> Unit,
    onNextQuestion: () -> Unit,
    onCloseAssessment: () -> Unit,
    navigateToAndPop: (Pair<String, String>) -> Unit,
    goBack: () -> Unit,
    assessmentType: String,
) {
    val context = LocalContext.current
    val activity = context.findActivity()
    val navigationBarHeightDp = activity?.getNavigationBarHeightInDp() ?: 0.dp
    val blur =
        if (uiState.isLoading) dimensionResource(dimen.default_screen_blur) else 0.dp
    val currentArtiIndex = remember { mutableStateOf(0) }

    if (uiState.questions.isNotEmpty()) {
        LazyColumn(
            Modifier
                .fillMaxSize()
                .padding(
                    top = dimensionResource(dimen.default_screen_padding),
                    start = dimensionResource(dimen.default_screen_padding),
                    end = dimensionResource(dimen.default_screen_padding)
                )
                .blur(blur)
        ) {
            item {
                CloseAssessment(
                    relatedSubSkillIdsJson = relatedSubSkillIdsJson,
                    uiState = uiState,
                    questionIndex = uiState.currentQuestionIndex,
                    isAnsweredQuestion = uiState.showAnswerFeedback,
                    onCloseAssessment = { onCloseAssessment() },
                    navigateToAndPop = navigateToAndPop,
                    goBack = goBack
                )
                AssessmentTitle(artiImages[currentArtiIndex.value], assessmentType)
                QuestionDotsIndicator(uiState.questionAnswersStatus)
                AssessmentQuestion(
                    thumbnail = uiState.getCurrentQuestionItem().thumbnail,
                    question = uiState.getCurrentQuestionItem().question
                )
                Spacer(modifier = Modifier.height(20.dp))
            }

            val optionsAbcLetterDescription = ('a'..'z').toList()
            // 判断当前选项是否存在带缩略图的条目
            val hasThumbnailOptions = uiState.currentAnswerOptions.any { it.thumbnail.isNotEmpty() }
            
            if (hasThumbnailOptions) {
                // 带缩略图时用网格布局展示选项
                item {
                    LazyVerticalGrid(
                        columns = GridCells.Fixed(2), // 可根据需求调整列数,比如用Adaptive实现自适应
                        horizontalArrangement = Arrangement.spacedBy(16.dp),
                        verticalArrangement = Arrangement.spacedBy(16.dp),
                        modifier = Modifier.fillMaxWidth()
                    ) {
                        itemsIndexed(uiState.currentAnswerOptions) { index, option ->
                            AnswerOption(
                                selectedOptionId = uiState.selectedAnswerId,
                                showFeedback = uiState.showAnswerFeedback,
                                optionLetter = circularCharIteration(optionsAbcLetterDescription, index),
                                option = option,
                                onSelectedOption = { onSelectedOption(it) }
                            )
                        }
                    }
                    Spacer(modifier = Modifier.height(20.dp))
                }
            } else {
                // 无缩略图时保持原列表布局
                itemsIndexed(uiState.currentAnswerOptions) { index, option ->
                    AnswerOption(
                        selectedOptionId = uiState.selectedAnswerId,
                        showFeedback = uiState.showAnswerFeedback,
                        optionLetter = circularCharIteration(optionsAbcLetterDescription, index),
                        option = option,
                        onSelectedOption = { onSelectedOption(it) }
                    )
                    Spacer(modifier = Modifier.height(12.dp))
                }
            }

            item {
                ChallengeBtn(
                    modifier = Modifier
                        .padding(bottom = navigationBarHeightDp + dimensionResource(dimen.default_screen_padding)),
                    uiState = uiState,
                    navigateToAndPop = navigateToAndPop,
                    onShowAnswerFeedback = { onShowAnswerFeedback(it) },
                    onCloseAssessment = { onCloseAssessment() },
                    onNextQuestion = {
                        if (!uiState.isLastQuestion) {
                            currentArtiIndex.value =
                                nextArtiImage(currentArtiIndex.value)
                            onNextQuestion()
                        }
                    } ,
                    relatedSubSkillIdsJson = relatedSubSkillIdsJson,
                )
            }
        }
    }
    ProgressBarComponentComposable(isLoading = uiState.isLoading)
}

关键修改点说明

  1. 添加布局判断逻辑:通过uiState.currentAnswerOptions.any { it.thumbnail.isNotEmpty() }判断是否需要切换到网格布局
  2. 嵌套LazyVerticalGrid:将网格布局作为LazyColumn的一个单独item,避免直接嵌套的布局冲突
  3. 网格布局配置:设置列数、间距等参数,可根据需求调整GridCells(比如GridCells.Adaptive(150.dp)实现自适应列宽)
  4. 保持原布局兼容:无缩略图时继续使用原有的列表渲染逻辑,保证页面行为一致性

可选扩展

如果需要单独将带缩略图的选项放在网格,不带的放在列表,可以先拆分选项列表:

val thumbnailOptions = uiState.currentAnswerOptions.filter { it.thumbnail.isNotEmpty() }
val nonThumbnailOptions = uiState.currentAnswerOptions.filter { it.thumbnail.isEmpty() }

然后分别渲染网格和列表部分即可。

内容的提问来源于stack exchange,提问作者user10625391

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 12:25:21