Отображение нескольких типов диалогов с разным текстом в Compose

Какой подход лучше всего подходит для отображения, например, двух типов диалогов на экране, а также параметризации сообщения для каждого диалога?На данный момент у меня есть запоминающееся изменяемое состояние переменная, которая представляет, должен ли диалог отображаться или нет, поэтому, если состояниеилиотобразит один из них. Но... что, если мне нужно параметризовать сообщение (или несколько переменных, таких как, например, изображение, но в данном случае это будет просто сообщение) для одного из этих диалогов? Должен ли я использовать другую переменную состояния запоминания со строкой? Если это так, то я использую две разные переменные состояния запоминания. Это верно?

Наверняка есть сложные способы добиться этого, создавая специальные классы данных, оборачивая их, передавая компонуемый контент в качестве параметров диалогу и т. д., но я стараюсь избегать таких сложных и перепрограммированных разработок и пытаюсь найти простой и легкий способ добиться этого.

Это пример кода, который я сделал:

      var dialogState by remember { mutableStateOf(DialogStateType.HIDDEN) }
var dialogMessage by remember { mutableStateOf("") }

В кнопках я изменяю состояние этих переменных следующим образом:

      onClick = {
    dialogMessage = "sample message text"
    dialogState = DialogStateType.MESSAGE
}) {

onClick = {
    dialogMessage = "sample confirmation dialog text"
    dialogState = DialogStateType.CONFIRMATION
}) {

И в основном составном я отображаю их, используя это:

      when (dialogState) {
    DialogStateType.MESSAGE -> {
        MessageDialog(dialogMessage) {
            dialogState = DialogStateType.HIDDEN
        }
    }

    DialogStateType.CONFIRMATION -> {
        ConfirmationDialog(dialogMessage,
            {
                CoroutineScope(Dispatchers.Default).launch {
                    //DO HARD JOB
                }
            },
            { dialogState = DialogStateType.HIDDEN },
            { dialogState = DialogStateType.HIDDEN })
    }
    DialogStateType.HIDDEN -> {}
}

Этот подход работает, и он прост, но кажется не слишком масштабируемым. Является ли это рекомендуемым способом сделать это? или есть более простой и легкий способ?

1 ответ

Аргументы Kotlin по умолчанию и?.let {...}может помочь

Некоторый класс, представляющий состояние:

      data class DialogState(val caption: String? = "Dialog",
                       val text: String? = null,
                       val imageResId: String? = null,
                       val confirmButtonText: String = "OK",
                       val cancelButtonText: String? = null,
                       val onConfirm: () -> Unit = {},
                       val onCancel: () -> Unit = {})

Общий диалог, составляющий как:

      @Composable
fun GenericDialog(dialogState: DialogState, onDismiss: () -> Unit) {
    Dialog(onDismissRequest = onDismiss) {
        Surface {
            Column(
                modifier = Modifier.padding(10.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                dialogState.caption?.let {
                    Text(text = dialogState.caption,
                        style = TextStyle(fontWeight = FontWeight.ExtraBold))
                    Spacer(modifier = Modifier.size(10.dp))
                }
                dialogState.imageResId?.let{
                    //show image
                    Spacer(modifier = Modifier.size(10.dp))
                }
                dialogState.text?.let {
                    Text(text = dialogState.text)
                    Spacer(modifier = Modifier.size(10.dp))
                }
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    Button(onClick = dialogState.onConfirm) {
                        Text(text = dialogState.confirmButtonText)
                    }
                    dialogState.cancelButtonText?.let {
                        Spacer(modifier = Modifier.size(10.dp))
                        Button(onClick = dialogState.onCancel) {
                            Text(text = dialogState.cancelButtonText)
                        }
                    }
                }
            }
        }
    }
}

А потом:

      var showDialog by remember { mutableStateOf(false) }
var dialogState = remember { DialogState() }
//...
if (showDialog) GenericDialog(dialogState = dialogState) { showDialog = false }
//...
Button(onClick = {
            dialogState = DialogState(caption = "Caption",
                text = "Text text text text text text text text text text text", 
                onConfirm = {showDialog = false})
            showDialog = true
        }) {
            Text(text = "Caption, text, one button")
        }
// or
Button(onClick = {
            dialogState = DialogState(caption = null,
                text = "Text text text text text text text text text text text",
                cancelButtonText = "Cancel",
                onConfirm = {showDialog = false},
                onCancel = {showDialog = false})
            showDialog = true
        }) {
            Text(text = "Text, two buttons")
        }
Другие вопросы по тегам