使用 Jetpack compose 检测在 RadioButton 中选择了什么答案

Detect what answer is selected in RadioButton using Jetpack compose

我正在尝试使用 Jetpack Compose 和 RadioButtons 做一个调查应用程序。 我创建了一个包含问题和答案的列表

val surveyQuestions = listOf(
   Question("question 1", listOf("answer 1", "answer 2")),
   Question("question 2", listOf("answer 1", "answer 2", "answer 3")),
   Question("question 3", listOf("answer 1", "answer 2"))
)

我还创建了一个视图(附件)。

如何将每个问题选择的答案数量限制为 1 个? 如何将调查结果保存为listOf(question1 - answer2, question2 - answer)等形式?

您需要将选择存储为 state。这取决于您的数据模型,例如您可以使用 mutableStateMapOf:

val selectionStates = remember { mutableStateMapOf<Int, Int>()}

surveyQuestions.forEachIndexed { i, question ->
    question.answers.forEachIndexed { j, answer ->
        RadioButton(selected = selectionStates[i] == j, onClick = { selectionStates[i] = j })
    }
}

如果您使用的是 Lazy 视图,可以将 forEachIndexed 替换为 itemsIndexed

您还可以将 selectionStates 从可组合项移动到 view model 以确保它不会被旋转破坏,以防您支持此操作。

我会将如此重要的信息作为列表存储在视图模型中,例如

var markedAnswers = mutableStateListOf<Int>()

然后添加更新机制

fun onAnswerUpdate(index: Int, newAnswer: Int){
 markedAnswer[index] = newAnswer
}

现在,只需将 getter 和 setter 传递给可组合项

MainActivity{
  val viewModel by viewModels<...>(()
  MyQuestionsComposable(
   answers = viewModel.markedAnswers,
   onAnswerUpdate = viewModel::onAnswerUpdate,
   ...
   )
}

@Composable
fun MyQuestionsComposable (
 questions: List<Question>, // I assume
 answers: List,
 onAnswerUpdate: (index, newAnswer) -> Unit
){
//I assume every question has three options for simplicity
/*and you must have access to the index of the question as it seems in the screenshot don't you?*/

//I'm using a loop for simplicity to gain the index, but you could do anything per your model
questions.forEachIndexed{ index, question ->
SurveyItem(
selectedAnswer = answers [index],
onAnswerUpdate = onAnswerUpdate,
options: List<...>
)
}

@Composable
fun SurveyItem(
selectedAnswer: Int,
options: List<...>,
onAnswerUpdate: (index, newAnswer) -> Unit
){
 options.forEachIndexed{index, option ->
  OptionComposable(
   modifier = Modifier.clickable(onClick = onAnswerUpdate(index, option)),
   selected = option == selectedAnswer
  )
 }
}
``

I'm storing selected answers as indices, and cross referencing them in the survey. Since it is mutable state, the selections will automatically update upon modification, and i have implemented this in a way that at a given time, only one answer can be selected.


I have followed Unidirectional Data Flow all over so it's best practiced. Don't worry about that.

Any doubts, just comment below.