【问题标题】:How to defer update to firebase from Compose TextField until user enters ImeAction.Done如何推迟从 Compose TextField 对 firebase 的更新,直到用户输入 ImeAction.Done
【发布时间】:2021-09-07 04:19:26
【问题描述】:

我试图仅在用户按下 TextField 中的 ImeAction.Done 后才推迟对 Firebase 数据库的更新。 (这样用户可以更新TextField,但我们只会在用户按下完成按钮时更新数据库。)

然而,这会导致 2 个事实来源(一个来自临时用户更新,另一个来自 firebase 数据库)。

如果我记得临时字段,则会反映用户更新,但当 firebase 进行第一次读取/或用户选择其他路径时,它不会更新。

//PROBLEM: tempDisplayName is only updated once and it will not register changes from firebase.
var tempDisplayName by remember {mutableStateOf(firebaseDataClass?.displayName?:"")} 
  
HoistDisplayName(tempDisplayName, { tempDisplayName = it}, 
     {
         firebaseDataClass?.displayname = tempDisplayName
         updateDatabase(firebaseDataClass)})

如果我使用 firebase 字段,那么当用户选择另一个路径时,会反映 Db 更改,但用户对 TextField 的更新不再有效。

//Now the field is updated when user selects another branch on firebase 
//(firebaseDataClass updated). 
//PROBLEM: user updates to the TextField is no longer reflected.
val tempDisplayName = firebaseDataClass?.displayName?:"" 

HoistDisplayName(tempDisplayName, { tempDisplayName = it}, 
     {
         firebaseDataClass?.displayname = tempDisplayName
         updateDatabase(firebaseDataClass)})

以下是 Hoisted 组合。

@Composable
private fun HoistDisplayName(
    display: String,
    onUpdate: (String) -> Unit,
    onDone: () -> Unit
) { 
    val localFocusManager = LocalFocusManager.current 
    OutlinedTextField(value = display,
        label = { Text(text = "Your name") }, 
        onValueChange = { onUpdate.invoke(it) },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
        keyboardActions = KeyboardActions {
            localFocusManager.clearFocus()
            onDone.invoke()
        }) 
}

那么我该如何修复这样的代码

  1. 来自 firebase 数据库的更新将反映在 TextField 上(替换所有临时更改)
  2. 临时更改也会显示在 TextField 上

【问题讨论】:

    标签: android kotlin firebase-realtime-database android-jetpack-compose


    【解决方案1】:

    您需要remember + mutableStateOf 才能使文本字段正常工作。

    当您的firebaseDataClass?.displayName 更改时,您需要更新它的值。为此,您需要将此值作为remember 键传递:当realDisplayName 与上次渲染时间不同时,tempDisplayName 将更新为新值。

    val realDisplayName = firebaseDataClass?.displayName?:""
    var tempDisplayName by remember(realDisplayName) { mutableStateOf(realDisplayName) }
    

    【讨论】:

      猜你喜欢
      • 2022-11-15
      • 1970-01-01
      • 2017-12-16
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 2020-06-01
      • 1970-01-01
      • 2015-12-17
      相关资源
      最近更新 更多