Home > OS >  How to pass selected single choice option to specific text field
How to pass selected single choice option to specific text field

Time:06-26

How can a selected option from a single choice menu be passed to a different composable to that it is displayed in a Text object? Would I need to modify the selectedOption value in some way?

@Composable
fun ScreenSettings(navController: NavController) {
    Scaffold(
        topBar = {...},
        content = {
            LazyColumn(...) {
                item {
                    ComposableSettingTheme()
                }
            }
        },
        containerColor = ...
    )
}

@Composable
fun ComposableSettingTheme() {
    val singleDialog = remember { mutableStateOf(false)}

    Column(modifier = Modifier
        .fillMaxWidth()
        .clickable(onClick = {
            singleDialog.value = true
        })) {
        Text(text = "Theme")
        Text(text = selectedOption) // selected theme name should be appearing here

        if (singleDialog.value) {
            AlertSingleChoiceView(state = singleDialog)
        }
    }
}

@Composable
fun CommonDialog(
    title: String?,
    state: MutableState<Boolean>,
    content: @Composable (() -> Unit)? = null
) {
    AlertDialog(
        onDismissRequest = {
            state.value = false
        },
        title = title?.let {
            {
                Column( Modifier.fillMaxWidth() ) {
                    Text(text = title)
                }
            }
        },
        text = content,
        confirmButton = {
            TextButton(onClick = { state.value = false }) { Text("OK") }
        },
        dismissButton = {
            TextButton(onClick = { state.value = false }) { Text("Cancel") }
        }
    )
}

@Composable
fun AlertSingleChoiceView(state: MutableState<Boolean>) {
    CommonDialog(title = "Theme", state = state) { SingleChoiceView(state = state) }
}

@Composable
fun SingleChoiceView(state: MutableState<Boolean>) {
    val radioOptions = listOf("Day", "Night", "System default")
    val (selectedOption, onOptionSelected) = remember { mutableStateOf(radioOptions[2]) }
    Column(
        Modifier.fillMaxWidth()
    ) {
        radioOptions.forEach { themeOption ->
            Row(
                Modifier
                    .clickable(onClick = { })
                    .selectable(
                        selected = (text == selectedOption),
                        onClick = {onOptionSelected(text)}
                    )
    ) {
                RadioButton(
                    selected = (text == selectedOption),
                    onClick = { onOptionSelected(text) }
                )
                Text(text = themeOption)
            }
        }
    }
}

enter image description here

Update

enter image description here

CodePudding user response:

According to official documentation, you should use state hoisting pattern.

Thus:

  1. Just take out selectedOption local variable to the "highest point of it's usage" (you use it in SingleChoiceView and ComposableSettingTheme methods) - ScreenSettings method.

  2. Then, add selectedOption: String and onSelectedOptionChange: (String) -> Unit parameters to SingleChoiceView and ComposableSettingTheme (You can get more info in documentation).

  3. Refactor your code using this new parameters:

    • Pass selectedOption local variable from ScreenSettings into SingleChoiceView and ComposableSettingTheme.

    • Write logic of onSelectedOptionChange - change local variable to new passed value

Hope I helped you!

  • Related