如何防止首次合成期间 TextField 上的初始 onFocus 触发

问题描述 投票:0回答:2

有什么方法可以在构图的初始布局过程中防止

onFocus
触发吗?,

.onFocusChanged {
   // initial pass triggers un-necessary onFocus callback with just `false` values
   Log.e("TextFieldFocusChanged", "${it.isFocused} : ${it.hasFocus}")
 }

我发现这个 Google 问题跟踪器似乎与此类行为相关,尽管该问题与组合的初始传递并不完全相关。

这个问题可以通过根据您的需要指定一些

boolean
标志来解决,但是根据您的用例,以这种方式处理它会慢慢引入复杂的
boolean
评估。有什么方法可以配置
TextField
来防止初始传递时
onFocus
回调吗?

提前谢谢您。

focus android-jetpack-compose textfield onfocus onfocuschangelistener
2个回答
1
投票

一定有更有效的方法来处理这个问题,但我现在能做的最理想的方法就是依靠

SideEffect

@Composable
fun ScreenTextFields() {

     //..TextField ... onFocusChanged { onTextFieldFocus(it) }...
     //..TextField ... onFocusChanged { onTextFieldFocus(it) }...
     //..TextField ... onFocusChanged { onTextFieldFocus(it) }...
     //..TextField ... onFocusChanged { onTextFieldFocus(it) }...

     SideEffect {
         // notify and update a boolean state (e.g onFieldsPostComposition)
     }
}

并且在国家课程中。

fun onTextFieldFocus(focusState: FocusState) {
     if (onFieldsPostComposition) {
         // do intended use-case on actual focus changes
     }
}

这样,任何初始

onFocus
回调都可以根据您的预期逻辑被忽略/跳过,唯一的部分是我不确定
onFocusChanged { ... }
回调是否是
composition/re-composition
的一部分,不确定是否有可能
SideEffect 
将在 onFocus 回调之前发生
first
,但到目前为止,这种方法适用于我的情况..


0
投票

事实上,您需要为此管理

boolean
标志。 首先,创建一个标志状态,并在第一个合成时将其设置为
true

var isInitialCompositionCompleted by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
    isInitialCompositionCompleted = true
}

其次,使用常规的

onFocusChanged
修饰符,然后简单地跳过所有回调,直到您的标志设置为
true
:

Modifier.onFocusChanged { focusState ->
    if (!isInitialCompositionCompleted) return@onFocusChanged
    onFocusChanged(focusState.isFocused)
}

这里

onFocusChanged(focusState.isFocused)
是你的外层 lambda。

© www.soinside.com 2019 - 2024. All rights reserved.