There is some unresolved situation that happens with my code, my target is to change the property of an item in the "devices" list (update a boolean), The change should cause recompose of the view, but that doesn't happen, In addition, I can see that the item indeed changes with the debugger, but it also causes to add an additional item(an old copy without the included change) to show up in my list.
Is there any idea how I was wrong with the new value assignment?
The ViewModel
private val _uiState = mutableStateOf(BTPairingState())
val uiState: State<BTPairingState> get() = _uiState
This is how i edit the item in the list
if (handlerDeviceResponse.status != null) {
viewModelScope.launch {
uiState.value.devices.find { it.macAddress == handlerDeviceResponse.device.macAddress }?.isConnected = handlerDeviceResponse.status
_uiState.value = uiState.value.copy()
}
}
BTPairingState:
data class BTPairingState (
val devices: MutableList<BtDeviceItemUiModel> = mutableListOf(),
val deviceType: DeviceType = DeviceType.RFID,
)
The Data class
data class BtDeviceItemUiModel(
val name: String,
val macAddress : String,
var isConnected: Boolean = false
)
The Screen:
@Destination
@Composable
fun BTPairScreen(
viewModel: BTPairViewModel = hiltViewModel(),
) {
val state = viewModel.uiState
BTPairDevices(state.value.devices) { viewModel.deviceItemClicked(it) }
CodePudding user response:
Replace var isConnected
by val isConnected
.
Then, replace val devices: MutableList<BtDeviceItemUiModel> = mutableListOf()
by val devices: List<BtDeviceItemUiModel> = emptyList()
.
IOW, stop using mutable values inside of your state.
Then, you can revise your code to update your MutableState
with a new value, using something like:
if (handlerDeviceResponse.status != null) {
val newDevices = uiState.value.devices.map { device ->
if (device.macAddress == handlerDeviceResponse.device.macAddress) {
device.copy(isConnected = handlerDeviceResponse.status)
} else {
it
}
}
_uiState.value = uiState.value.copy(devices = newDevices)
}
CodePudding user response:
In your viewmodel Change state to StateFlow
private val _uiState = MutableStateFlow(BTPairingState())
val uiState: StateFlow<BTPairingState> = _uiState.asStateFlow()
In your BTPairScreen Instead of
val state = viewModel.uiState
Use:
val state by viewModel.state.collectAsState()