Как реализовать двунаправленную синхронизацию ввода текстового поля между моделью представления и композицией?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как реализовать двунаправленную синхронизацию ввода текстового поля между моделью представления и композицией?

Сообщение Anonymous »

Я использую ту же модель представления/композиционную пару для формы создания и формы редактирования. В форме создания текстовый ввод начинается как пустой, но в форме редактирования начальный текст ввода происходит из базы данных. В модели представления я объединяю ввод, который поступает из базы данных с текущим текстовым вводом, чтобы показать различные состояния для пользователя. Я создал TextFieldState в композитном обработке ввода текстового поля на конце пользовательского интерфейса, и Stateflow в модели представления для обработки ввода на этой стороне. У меня проблемы с синхронизацией данных двунаправленной. Последнее значение должно поступить из пользовательского интерфейса, но начальное значение должно поступить из базы данных. Вот упрощенный пример: < /p>
data class FormUiState(val name: String, val changed: Boolean)

class FormViewModel : ViewModel() {
private val name = MutableStateFlow("")

val uiState = combine(name, getExistingNameFromDb()) { name, existingName ->
FormUiState(
name = name,
changed = name != existingName,
)
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000L),
FormUiState(name = "", changed = false)
)

init {
viewModelScope.launch {
name.value = getExistingNameFromDb().first()
}
}

fun updateName(value: String) {
name.value = value
}

private fun getExistingNameFromDb() = flowOf("foo")
}

@Composable
fun FormScreen(modifier: Modifier = Modifier, viewModel: FormViewModel = viewModel()) {
val name = rememberTextFieldState()
val uiState by viewModel.uiState.collectAsStateWithLifecycle()

LaunchedEffect(name) {
snapshotFlow { name.text.toString() }.collect { viewModel.updateName(it) }
}

LaunchedEffect(uiState.name) {
if (uiState.name != name.text) {
name.setTextAndPlaceCursorAtEnd(uiState.name)
}
}

Column(modifier = modifier) {
OutlinedTextField(state = name, label = { Text("Name") })
Text(text = "Changed: ${uiState.changed}")
}
}
< /code>
С тем, что я реализовал сейчас, я могу получить значение только в одну сторону от пользовательского интерфейса в модель представления. Я также попытался использовать текстовое поле, основанное на значении, но оно приводит к тому, что обновления ввода текста в пользовательском интерфейсе пропустили некоторые значения. Я также попытался перенести TextFieldState в модель представления, но тогда я не могу запустить тесты модели представления.>

Подробнее здесь: https://stackoverflow.com/questions/797 ... view-model
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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