android 我如何在Kotlincompose中修复我的警告对话框?

mcvgt66p  于 2022-11-20  发布在  Android
关注(0)|答案(1)|浏览(187)

我一直在做一个字典应用程序有一段时间了,我补充说,用户可以创建自己的字典在我的应用程序上。我显示用户的字典在屏幕上,用户可以删除他们的字典,无论他们想要什么。所以我试图使警报对话框,因为我希望用户不要删除他们的字典时,他们直接按下删除图标。屏幕上会出现一个警告对话框,在那个警告对话框中应该有两个按钮,比如取消和接受。如果用户按下接受,也就是说,如果他想删除,我希望字典被删除。
然而,问题是在编写和我写的代码中很难实现这一点,因为我遇到了很多问题,而这本应该很容易。我在我的代码中所做的是,如果用户单击删除图标,onDeleteClick将工作,showAlertDialogonDeleteClick中变为true。当为true时,它进入顶部的if块并调用alertdialog组件。当alertdialog组件被调用时,CustomDialogUI打开。我向CustomDialogUI发送了两个参数,一个是showAlertDialog的mutablestate,它控制alertdialog的打开并且第二个是deleteDicState。如果用户在打开的警告对话框中说允许,则deleteDicState变为真,并且如果deleteDicState为真,则必须进行删除。
由于deleteDicState第一次是假的,它不删除,但当警报对话框第二次打开,我说删除,它删除它出于某种原因,我如何解决这个问题的帮助。

我的代码

@Composable
fun CreateYourOwnDictionaryScreen(
    navController: NavController,
    viewModel: CreateYourOwnDictionaryViewModel = hiltViewModel()
) {

    val scaffoldState = rememberScaffoldState()
    val state = viewModel.state.value

    val scope = rememberCoroutineScope()

    val context = LocalContext.current
    val showAlertDialog = remember { mutableStateOf(false) }
    val deleteDicState = remember { mutableStateOf(false) }


    if(showAlertDialog.value){

        Dialog(onDismissRequest = { showAlertDialog.value = false }) {
            CustomDialogUI(openDialogCustom = showAlertDialog,deleteDicState)
        }

    }


    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {
            TopAppBar(
                backgroundColor = bar,
                title = {

                    androidx.compose.material3.Text(
                        text = "your dictionaries",
                        modifier = Modifier.fillMaxWidth(),
                        color = Color.White,
                        fontSize = 22.sp
                    )

                },
                navigationIcon = {
                    IconButton(onClick = {
                        navController.navigate(Screen.MainScreen.route)
                    }) {
                        Icon(
                            imageVector = Icons.Filled.ArrowBack,
                            contentDescription = "Go Back"
                        )
                    }
                }

            )

        },

        floatingActionButtonPosition = FabPosition.Center,
        floatingActionButton = {
            FloatingActionButton(
                onClick = { navController.navigate(Screen.CreateDicScreen.route) },
                backgroundColor = bar,

                ) {
                Icon(Icons.Filled.Add, "fab")
            }
        }
    ) {

        Box(modifier = Modifier.background(MaterialTheme.colors.background)) {

            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp)
            ) {

                LazyColumn(
                    modifier = Modifier.fillMaxSize()
                ) {
                    items(state.dictionaries) { dictionary ->

                        CreateYourOwnDictionaryItem(
                            dictionary = dictionary,
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable {
                                    navController.navigate(Screen.MyWordsScreen.passDicId(dictionary.uid))
                                },

                            onAddClick = {
                                navController.navigate(
                                    Screen.MakeYourDictionaryScreen.passDicId(
                                        dictionary.uid
                                    )
                                )
                            },

                            onDeleteClick = {

                                if(deleteDicState.value){
                                    viewModel.onEvent(
                                        CreateYourOwnDictionaryEvents.DeleteDictionary(dictionary)
                                    )

                                    scope.launch {
                                        val result = scaffoldState.snackbarHostState.showSnackbar(
                                            message = "dictionary is deleted",
                                            /*actionLabel = "Undo",*/
                                            duration = SnackbarDuration.Short
                                        )
                                    }
                                }


                            },
                            onEditClick = {

                                navController.navigate(
                                    Screen.UpdateOwnDictionaryScreen.passDicIdAndDicName(
                                        dictionary.uid,
                                        dictionary.creationTime,
                                    )
                                )

                            }

                        )
                    }
                }

            }
        }

    }

}

@Composable
fun CustomDialogUI(
    openDialogCustom: MutableState<Boolean>,
    deleteDicState : MutableState<Boolean>
    )  {

    Card(
        //shape = MaterialTheme.shapes.medium,
        shape = RoundedCornerShape(10.dp),
        // modifier = modifier.size(280.dp, 240.dp)
        modifier = Modifier.padding(10.dp, 5.dp, 10.dp, 10.dp),
        elevation = 8.dp
    ) {
        Column(
            modifier = Modifier
                .background(Color.White)
        ) {

            //.......................................................................
            Image(
                painter = painterResource(id = R.drawable.ic_baseline_warning),
                contentDescription = null, // decorative
                /*contentScale = ContentScale.Fit,
                colorFilter = ColorFilter.tint(
                    color = bar
                ),*/
                modifier = Modifier
                    .padding(top = 35.dp)
                    .height(70.dp)
                    .fillMaxWidth(),

                )

            Column(modifier = Modifier.padding(16.dp)) {
                androidx.compose.material3.Text(
                    text = "Warning !",
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .padding(top = 5.dp)
                        .fillMaxWidth(),
                    style = MaterialTheme.typography.body2,
                    maxLines = 2,
                    overflow = TextOverflow.Ellipsis
                )
                androidx.compose.material3.Text(
                    text = "Are you sure that your previously created dictionary will be deleted?",
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .padding(top = 10.dp, start = 25.dp, end = 25.dp)
                        .fillMaxWidth(),

                    )
            }
            //.......................................................................
            Row(
                Modifier
                    .fillMaxWidth()
                    .padding(top = 10.dp)
                    .background(bar),
                horizontalArrangement = Arrangement.SpaceAround
            ) {

                TextButton(onClick = {
                    openDialogCustom.value = false
                }) {

                    Text(
                        "Not Now",
                        fontWeight = FontWeight.Bold,
                        color = Color.Black,
                        modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
                    )
                }
                TextButton(onClick = {
                    openDialogCustom.value = false
                    deleteDicState.value = true
                }) {
                    Text(
                        "Allow",
                        fontWeight = FontWeight.ExtraBold,
                        color = Color.Black,
                        modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
                    )
                }
            }
        }
    }


}

我不能在onDeleteClick中调用CustomDialogUI。如果我调用它,它会给出以下错误@Composable invocations can only happen from the context of a @Composable function

例如这样
一米十三分一秒

onDeleteClick = {

                                Dialog(onDismissRequest = { showAlertDialog.value = false }) {
                                    CustomDialogUI(openDialogCustom = showAlertDialog,deleteDicState)
                                }
....

"我不能这样打电话"
因此,我在onDeleteClick外部调用它,或者直接在CustomDialogUI中调用它。如果用户按下删除按钮,我无法在那里删除它,因为我无法在那里访问viewmodel和字典

例如这样
一月十六日一月

TextButton(onClick = {
                    openDialogCustom.value = false
                  
                    viewModel.onEvent(
                        CreateYourOwnDictionaryEvents.DeleteDictionary(dictionary)
                    )

                    scope.launch {
                        val result = scaffoldState.snackbarHostState.showSnackbar(
                            message = "dictionary is deleted",
                            /*actionLabel = "Undo",*/
                            duration = SnackbarDuration.Short
                        )
                    }
                
                }) {
                    Text(
                        "Allow",
                        fontWeight = FontWeight.ExtraBold,
                        color = Color.Black,
                        modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
                    )
                }
            }

"我不能这样打电话"

0yg35tkg

0yg35tkg1#

MutableState s作为可组合参数传递被认为是一种不好的做法,您应该改为传递原始值和回调。在您的情况下,您可以这样实现它:

@Composable
fun CreateYourOwnDictionaryScreen() {
    val showDeleteDialogForItem = remember { mutableStateOf<DictionaryItem?>(null) }

    showDeleteDialogForItem.value?.let { itemToDelete ->
        DeleteDialog(
            onDeleteConfirm = {
                viewModel.onEvent()
                showDeleteDialogForItem = null
            },
            onCancel = { showDeleteDialogForItem = null },
        )
    }
    
    ...
    items.forEach { item ->
        CreateYourOwnDictionaryItem(
             onDeleteClick = { showDeleteDialogForItem.value = item }
        )
    }
}

@Composable
fun DeleteDialog(
    onDeleteConfirm: () -> Unit,
    onCancel: () -> Unit,
) {
   ...
   Button(onClick = onCancel) { Text("Cancel") }
   Button(onClick = onDeleteConfirm) { Text("Delete") }
}

相关问题