Cursor is jumping one position to the left while typing when i try to save the value of an OutlinedTextField within onValueChange

huangapple go评论92阅读模式
英文:

Cursor is jumping one position to the left while typing when i try to save the value of an OutlinedTextField within onValueChange

问题

以下是您要翻译的内容:

"I'm having some problems using the OutlinedTextField and connecting to my DataStore where I store my user settings. The data is saved and read correctly. However, there seems to be a problem updating the display and the cursor. When I enter a text (probably because I was typing too fast), the cursor jumps one position to the left. This corrupts the input and the user experience is pretty bad.

So far I haven't been able to find a solution to fix the problem.
Do you have an idea what it could be?
Thank you very much!

Thats the code i use for my OutlinedTextField:

OutlinedTextField(
    value = dataStoreState.nickname,
    onValueChange = {
        CoroutineScope(Dispatchers.IO).launch {
            viewModel.saveToDataStore(dataStoreState.copy(nickname = it))
        }
    },
    label = { Text(stringResource(id = R.string.enterNickname)) },
    keyboardOptions = KeyboardOptions.Default.copy(
        keyboardType = KeyboardType.Text,
        imeAction = ImeAction.Done
    ),
    modifier = Modifier.fillMaxWidth()
)

I tried to cache the text value in another variable, that had no effect.
Then I tried to change the save function, but I couldn't find a correct solution here either."

英文:

I'm having some problems using the OutlinedTextField and connecting to my DataStore where I store my user settings. The data is saved and read correctly. However, there seems to be a problem updating the display and the cursor. When I enter a text (probably because I was typing too fast), the cursor jumps one position to the left. This corrupts the input and the user experience is pretty bad.

So far I haven't been able to find a solution to fix the problem.
Do you have an idea what it could be?
Thank you very much!

Thats the code i use for my OutlinedTextField:

OutlinedTextField(
    value = dataStoreState.nickname,
    onValueChange = {
        CoroutineScope(Dispatchers.IO).launch {
            viewModel.saveToDataStore(dataStoreState.copy(nickname = it))
        }
    },
    label = { Text(stringResource(id = R.string.enterNickname)) },
    keyboardOptions = KeyboardOptions.Default.copy(
        keyboardType = KeyboardType.Text,
        imeAction = ImeAction.Done
    ),
    modifier = Modifier.fillMaxWidth()
) 

I tried to cache the text value in another variable, that had no effect.
Then I tried to change the save function, but I couldn't find a correct solution here either.

答案1

得分: 4

更新文本字段状态必须是同步的,你不能让协程更新你的存储,然后只在它完成后更新文本字段。你需要重新设计这个,以确保状态立即更新,然后你可以考虑将当前文本推送到一个 SnapshotFlow 中,对其进行防抖处理,然后从流中进行更新。

类似这样的代码:

var text by remember {
    mutableStateOf("")
}
LaunchedEffect(key1 = Unit) {
    text = datastoreState.nickname
    snapshotFlow { text }
        .debounce(500L)
        .distinctUntilChanged()
        .onEach {
            viewModel.saveToDataStore(dataStoreState.copy(nickname = it))
        }
        .launchIn(this)
}
OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text(stringResource(id = R.string.enterNickname)) },
    keyboardOptions = KeyboardOptions.Default.copy(
        keyboardType = KeyboardType.Text,
        imeAction = ImeAction.Done
    ),
    modifier = Modifier.fillMaxWidth()
)
英文:

Updates to the text field state must be synchronous, you can't have a coroutine updating your store and only update the text field after that completes. You will have to rework this to ensure the state updates immediately, then you can maybe push the current text to a snapshotflow, debounce that and update from the flow.

Something like this

var text by remember {
    mutableStateOf("")
}
LaunchedEffect(key1 = Unit) {
    text = datastoreState.nickname
    snapshotFlow { text }
        .debounce(500L)
        .distinctUntilChanged()
        .onEach {
            viewModel.saveToDataStore(dataStoreState.copy(nickname = it))
        }
        .launchIn(this)
}
OutlinedTextField(
    value = text,
    onValueChange = { text = it },
    label = { Text(stringResource(id = R.string.enterNickname)) },
    keyboardOptions = KeyboardOptions.Default.copy(
        keyboardType = KeyboardType.Text,
        imeAction = ImeAction.Done
    ),
    modifier = Modifier.fillMaxWidth()
)

huangapple
  • 本文由 发表于 2023年5月22日 05:10:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301939.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定