Я разрабатываю экран с формой для ввода данных о пассажирах с помощью Jetpack Compose. Функция формирования данных о пассажирах интегрирована в функцию экрана. При нажатии кнопки «Сохранить» ViewModel проверяет введенные данные и обновляет состояние пассажира с ошибками, если таковые обнаружены. Я хочу, чтобы ViewModel сигнализировал форме пассажира о необходимости прокрутки до первого ошибочного поля при обнаружении ошибок. Однако я не уверен, как реализовать это действие во вложенной функции формы пассажира.
Я попытался передать NeedScroll SharedFlow из ViewModel. В ViewModel я передаю значение Unit в SharedFlow после обновления состояния пассажира. Однако проблема возникает, когда значение из SharedFlow собирается PassengerForm до того, как будет получено новое состояние пассажира, содержащее ошибки.
class MyViewModel : ViewModel() {
private val _passengerState = MutableStateFlow(PassengerState())
val passengerState = _passengerState.asStateFlow()
private val _needScroll = MutableSharedFlow()
val needScroll = _needScroll.asSharedFlow()
fun onChangeField1(value: String) {
_passengerState.update {
it.copy(field1 = it.field1.copy(value = value, isError = false))
}
}
fun onChangeField2(value: String) {
_passengerState.update {
it.copy(field2 = it.field2.copy(value = value, isError = false))
}
}
fun onSave() {
val cueState = _passengerState.value
if (cueState.field1.value.isEmpty() || cueState.field2.value.isEmpty()) {
_passengerState.update {
it.copy(
field1 = it.field1.copy(isError = cueState.field1.value.isEmpty()),
field2 = it.field2.copy(isError = cueState.field2.value.isEmpty()),
)
}
viewModelScope.launch {
_needScroll.emit(Unit)
}
}
}
}
@Composable
fun MyScreen(
viewModel: MyViewModel,
) {
val passengerState by viewModel.passengerState.collectAsStateWithLifecycle()
val needScroll = remember { mutableStateOf(viewModel.needScroll) }
MyPassengerForm(
passengerState = passengerState,
needScroll = needScroll,
onChangeField1 = remember { { viewModel.onChangeField1(it) } },
onChangeField2 = remember { { viewModel.onChangeField2(it) } },
onSave = remember { { viewModel.onSave() } },
)
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyPassengerForm(
passengerState: PassengerState,
needScroll: State,
onChangeField1: (String) -> Unit,
onChangeField2: (String) -> Unit,
onSave: () -> Unit,
) {
val lifecycle = LocalLifecycleOwner.current.lifecycle
val field1BringIntoView = remember { BringIntoViewRequester() }
val field2BringIntoView = remember { BringIntoViewRequester() }
LaunchedEffect(key1 = passengerState, key2 = needScroll) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
needScroll.value.collect {
val bringIntoView = when {
passengerState.field1.isError -> field1BringIntoView
passengerState.field2.isError -> field2BringIntoView
else -> null
}
launch {
bringIntoView?.bringIntoView()
}
}
}
}
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
TextField(
modifier = Modifier.bringIntoViewRequester(field1BringIntoView),
value = passengerState.field1.value,
onValueChange = onChangeField1,
)
TextField(
modifier = Modifier.bringIntoViewRequester(field2BringIntoView),
value = passengerState.field2.value,
onValueChange = onChangeField2,
)
Button(onClick = onSave) {
Text(text = "Save")
}
}
}
data class PassengerState(
val field1: FieldItem = FieldItem(),
val field2: FieldItem = FieldItem(),
)
data class FieldItem(
val value: String = "",
val isError: Boolean = false,
)
Подробнее здесь: https://stackoverflow.com/questions/783 ... composable
Передача действия вложенному составному элементу ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1713272436
Anonymous
Я разрабатываю экран с формой для ввода данных о пассажирах с помощью Jetpack Compose. Функция формирования данных о пассажирах интегрирована в функцию экрана. При нажатии кнопки «Сохранить» ViewModel проверяет введенные данные и обновляет состояние пассажира с ошибками, если таковые обнаружены. Я хочу, чтобы ViewModel сигнализировал форме пассажира о необходимости прокрутки до первого ошибочного поля при обнаружении ошибок. Однако я не уверен, как реализовать это действие во вложенной функции формы пассажира.
Я попытался передать NeedScroll SharedFlow из ViewModel. В ViewModel я передаю значение Unit в SharedFlow после обновления состояния пассажира. Однако проблема возникает, когда значение из SharedFlow собирается PassengerForm до того, как будет получено новое состояние пассажира, содержащее ошибки.
class MyViewModel : ViewModel() {
private val _passengerState = MutableStateFlow(PassengerState())
val passengerState = _passengerState.asStateFlow()
private val _needScroll = MutableSharedFlow()
val needScroll = _needScroll.asSharedFlow()
fun onChangeField1(value: String) {
_passengerState.update {
it.copy(field1 = it.field1.copy(value = value, isError = false))
}
}
fun onChangeField2(value: String) {
_passengerState.update {
it.copy(field2 = it.field2.copy(value = value, isError = false))
}
}
fun onSave() {
val cueState = _passengerState.value
if (cueState.field1.value.isEmpty() || cueState.field2.value.isEmpty()) {
_passengerState.update {
it.copy(
field1 = it.field1.copy(isError = cueState.field1.value.isEmpty()),
field2 = it.field2.copy(isError = cueState.field2.value.isEmpty()),
)
}
viewModelScope.launch {
_needScroll.emit(Unit)
}
}
}
}
@Composable
fun MyScreen(
viewModel: MyViewModel,
) {
val passengerState by viewModel.passengerState.collectAsStateWithLifecycle()
val needScroll = remember { mutableStateOf(viewModel.needScroll) }
MyPassengerForm(
passengerState = passengerState,
needScroll = needScroll,
onChangeField1 = remember { { viewModel.onChangeField1(it) } },
onChangeField2 = remember { { viewModel.onChangeField2(it) } },
onSave = remember { { viewModel.onSave() } },
)
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyPassengerForm(
passengerState: PassengerState,
needScroll: State,
onChangeField1: (String) -> Unit,
onChangeField2: (String) -> Unit,
onSave: () -> Unit,
) {
val lifecycle = LocalLifecycleOwner.current.lifecycle
val field1BringIntoView = remember { BringIntoViewRequester() }
val field2BringIntoView = remember { BringIntoViewRequester() }
LaunchedEffect(key1 = passengerState, key2 = needScroll) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
needScroll.value.collect {
val bringIntoView = when {
passengerState.field1.isError -> field1BringIntoView
passengerState.field2.isError -> field2BringIntoView
else -> null
}
launch {
bringIntoView?.bringIntoView()
}
}
}
}
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
TextField(
modifier = Modifier.bringIntoViewRequester(field1BringIntoView),
value = passengerState.field1.value,
onValueChange = onChangeField1,
)
TextField(
modifier = Modifier.bringIntoViewRequester(field2BringIntoView),
value = passengerState.field2.value,
onValueChange = onChangeField2,
)
Button(onClick = onSave) {
Text(text = "Save")
}
}
}
data class PassengerState(
val field1: FieldItem = FieldItem(),
val field2: FieldItem = FieldItem(),
)
data class FieldItem(
val value: String = "",
val isError: Boolean = false,
)
Подробнее здесь: [url]https://stackoverflow.com/questions/78333459/passing-an-action-to-a-nested-composable[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия