我正在尝试创建一个debounce可点击的组合修饰符,如下面的代码片段。
inline fun Modifier.debounceClickable(
debounceInterval: Long = 400,
crossinline onClick: () -> Unit,
): Modifier = composed {
var lastClickTime = 0L
clickable() {
val currentTime = System.currentTimeMillis()
if ((currentTime - lastClickTime) < debounceInterval) return@clickable
lastClickTime = currentTime
onClick()
}
}
不确定IDE为什么警告不必要使用modifier .compose
?顺便问一下,这个脱线器有潜在的危险或泄漏吗?
您只需要使用composed
拨打@Composable
。
注意,在composed
中,你应该只使用状态注释的可组合物,就像使用remember
保存一些状态一样,而不是可组合视图。
inline fun Modifier.debounceClickable(
debounceInterval: Long = 400,
crossinline onClick: () -> Unit,
): Modifier {
var lastClickTime = 0L
return clickable() {
val currentTime = System.currentTimeMillis()
if ((currentTime - lastClickTime) < debounceInterval) return@clickable
lastClickTime = currentTime
onClick()
}
}
和你现在的代码一样。
问题是你在lastClickTime
中存储数据,并且在你的代码中,一旦第一次重组发生,它将被重置。只有当你不改变UI的动作,它可能工作得很好。
您可以使用以下核心进行测试:
var flag by remember { mutableStateOf(false) }
Text("clickable $flag", Modifier.debounceClickable { flag = !flag } )
这就是为什么你实际上需要composed
来存储这个值使用remember
和mutableStateOf
,就像在任何其他视图:
inline fun Modifier.debounceClickable(
debounceInterval: Long = 400,
crossinline onClick: () -> Unit,
): Modifier = composed {
var lastClickTime by remember { mutableStateOf(0L) }
clickable() {
val currentTime = System.currentTimeMillis()
if ((currentTime - lastClickTime) < debounceInterval) return@clickable
lastClickTime = currentTime
onClick()
}
}
我建议你去看看state in Compose文档,包括这个youtube视频,它解释了基本原理。