Показание диалога с проверкой ошибок с помощью JetPack ComposeAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Показание диалога с проверкой ошибок с помощью JetPack Compose

Сообщение Anonymous »

Я строю приложение Todo List. Когда пользователь нажимает на значок «Добавить», появляется диалог, позволяющий им добавить задачу в список. После нажатия «Подтвердить» в диалоговом окне событие CLICK должно вызвать обратный вызов, который делегирует обработку ошибок в ViewModel. Когда ViewModel определяет ошибку, она обновляет MutableStateFlow, который собирается в представлении. Как только представление обнаружит ошибку, он должен отобразить ошибку в диалоговом окне «Открыть». Я пытаюсь найти способ закрыть диалог после того, как «Подтверждение» нажимается, не предотвращая открытие диалога в первую очередь (нажав Add). До сих пор, когда проверка проходит и в настоящее время открыт диалог, я хочу закрыть диалог, поэтому я установил < /p>

Код: Выделить всё

if (!verificationFailed && isDialogOpen) isDialogOpen = false
< /code>
Но, поскольку проверка запускается как false, когда нажат значок добавления, что условия является истинной, которая предотвращает появление диалога в первую очередь.import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.example.todopractice.ui.theme.ToDoPracticeTheme
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
private val vm by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
ToDoPracticeTheme {
var isDialogOpen by rememberSaveable { mutableStateOf(false) }
val tasks by vm.tasks.collectAsState()
val verificationFailed by vm.inputError.collectAsState()

Scaffold(
modifier = Modifier.fillMaxSize(),
topBar = {
AppBar(
{
isDialogOpen = true
vm.clearError()
Log.d("TRACE", "+ icon was clicked, isDialogOpen=$isDialogOpen")
}
)
}) { innerPadding ->
//}
LazyColumn {
Log.d("TRACE", "$tasks")
items(tasks) {
TaskRow(it)
}
}

if (!verificationFailed &&  isDialogOpen) isDialogOpen = false
if (isDialogOpen) InsertTaskDialog(
onNegativeClick = {
isDialogOpen = false
vm.clearError() // Uncomment if you add this function
},
onPositiveClick = {
vm.onSubmitTask(it)
},
verificationFailed
)
}
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppBar(onOpenDialogClick: ()->Unit) {
TopAppBar(
title = { Text("ToDo") },
actions = {
IconButton(onClick = { onOpenDialogClick() }) {
Icon(imageVector = Icons.Default.Add, contentDescription = "Open Dialog")
}
}
)
}

@Composable
fun TaskRow(task: Task) {
Row {
Text(text = task.name)
}
}

@Composable
fun InsertTaskDialog(
onNegativeClick: ()->Unit,
onPositiveClick: (Task)->Unit,
verificationFailed: Boolean) {
var nameInput by rememberSaveable { mutableStateOf("") }

AlertDialog(
onDismissRequest = onNegativeClick,
confirmButton = {
Button(onClick = {
onPositiveClick(Task(nameInput,false))
}) {
Text(text = "Confirm")
} },
modifier = Modifier,
dismissButton = {
Button(onClick = { onNegativeClick() }) {
Text(text = "Cancel")
} },
title = { Text(text = "New Task") },
text = {
Column {
OutlinedTextField(
value = nameInput,
onValueChange = { nameInput = it },
label = { Text(text = "Name") }
)
if (verificationFailed) {
Spacer(modifier = Modifier.height(8.dp))
Text(text = "Name is required", color = Color.Red)
}
}
}
)
}
}
< /code>
mainviewmodel < /p>
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

data class Task(val name: String, val isComplete: Boolean)

class MainViewModel: ViewModel() {
private val _tasks = MutableStateFlow(listOf())
val tasks = _tasks.asStateFlow()

private val _inputError = MutableStateFlow(false)
val inputError = _inputError.asStateFlow()

fun onSubmitTask(task: Task) {
if (task.name.isEmpty()) {
_inputError.update { true }
} else {
_inputError.update { false }
_tasks.update {
it + task
}
}
}

fun clearError() {
_inputError.update { false }
}
}
Я знаю, что мог бы избежать этого, проверив ошибку внутри моего композиции, но я бы хотел, чтобы TP помещал эту логику в моем ViewModel, чтобы сделать ее проверкой.>

Подробнее здесь: https://stackoverflow.com/questions/797 ... ck-compose
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»