在jetpack compose中使用多个键避免在LaunchEffect中重复调用



我想避免在LaunchEffect键触发时调用多个函数。

LaunchedEffect(key1 = isEnableState, key2 = viewModel.uiState) {
viewModel.scanState(bluetoothAdapter)
}

当第一次合成isEnableStateviewModel.uiState时,都将触发两次并调用viewModel.scanState(bluetoothAdapter)

isEnableStateBoolean类型,viewModel.uiState是UI类型的密封类。

var uiState by mutableStateOf<UIState>(UIState.Initial)
private set 
var isEnableState by mutableStateOf(false)
private set

那么我们如何处理习惯的方法来避免重复调用呢?

感谢

更新ContentStateful

@Composable
fun ContentStateful(
context: Context = LocalContext.current,
viewModel: ContentViewModel = koinViewModel(),
) {
LaunchedEffect(key1 = viewModel.isEnableState, key2 = viewModel.uiState) {
viewModel.scanState(bluetoothAdapter)
}
LaunchedEffect(viewModel.previous) {
viewModel.changeDeviceSate()
}
ContentStateLess{
viewModel.isEnableState = false
}
}

ContentStateLess

@Composable
fun ContentStateLess(changeAction: () -> Unit) {
Button(onClick = { changeAction() }) {
Text(text = "Click On me")
}
}

ContentViewModel

class ContentViewModel : BaseViewModel() {
var uiState by mutableStateOf<UIState>(UIState.Initial)
var isEnableState by mutableStateOf(false)

fun scanState(bluetoothAdapter: BluetoothAdapter) {
if (isEnableState && isInitialOrScanningUiState()) {
// start scanning
} else {
// stop scanning
}
}
private fun isInitialOrScanningUiState(): Boolean {
return (uiState == UIState.Initial || uiState == UIState.ScanningDevice)
}
fun changeDeviceSate() {
if (previous == BOND_NONE && newState == BONDING) {
uiState = UIState.LoadingState
} else if (previous == BONDING && newState == BONDED) {
uiState = UIState.ConnectedState(it)
} else {
uiState = UIState.ConnectionFailedState
}
}
}

scanState功能是启动和停止扫描设备。

我猜下面的答案可能会起作用,或者可能需要一些修改才能起作用,但防止双击的逻辑只能在您希望在小间隔的时间框架内防止操作最初发生时使用。为了防止双击,您可以设置当前时间并再次检查时间是否高于阈值以调用单击回调。在您的情况下,添加延迟状态可能会解决问题。

IDLE, BUSY, READY

var launchState by remember {mutableStateOf(IDLE)}
LaunchedEffect(key1 = isEnableState, key2 = viewModel.uiState) {
if(launchState != BUSY){
viewModel.scanState(bluetoothAdapter)
if(launchState == IDLE){ launchState = BUSY)
}
}

LaunchedEffect(launchState) {
if(launchState == BUSY){
delay(50)
launchState = READY
}
}

相关内容

  • 没有找到相关文章

最新更新