Search code examples
androidlistkotlinandroid-jetpack-composecompose-recomposition

Composable not recomposing when list is cleared in jetpack compose


I have one MutableStateFlow which is kind of emptyList. When I add the item my view is recomposed without any problem. Now I want to recompose view when list is clear. I tried some piece of code but nothing happens.

PairViewModel

class PairViewModel : BaseViewModel() {
     val scanLowEnergyDevices by lazy { MutableStateFlow(emptyList<ScanResult>()) }

     fun addDevices(result: ScanResult) {
        scanLowEnergyDevices.value += result
    }
}

ContentStateful

@Composable
fun ContentStateful(
    context: Context = LocalContext.current,
    viewModel: BloodPressurePairViewModel = getViewModel()
) {
    val activity = context as ComponentActivity
    val scanDeviceList by viewModel.scanLowEnergyDevices.collectAsStateWithLifecycle()
  
    ContentStateLess(
        scanDeviceList = scanDeviceList,
        resetAction = {
            viewModel.scanLowEnergyDevices.value.toMutableList().clear()
        }   
    )
}

ContentStateLess

@Composable
fun ContentStateLess(
    scanDeviceList: List<ScanResult>,
    resetAction: () -> Unit,
) {
    AnimatedVisibility(visible = scanDeviceList.isNotEmpty()) {
        Text(text = "scanDeviceList ${scanDeviceList.size}")
        Button(onClick = { resetAction() }) {
            Text(text = "Reset")
        }
    }
}

What is wrong in here? Thanks


Solution

  • Try to use SnapshotStateList like this

    val scanLowEnergyDevices by lazy { mutableStateListOf<ScanResult>() }
    

    add items like this

    fun addDevices(result: ScanResult) {
        scanLowEnergyDevices.add(result)
        // scanLowEnergyDevices.value.add(result)
    }
    

    and clear the list like you would do with a standard collection like this

    resetAction = {
        viewModel.scanLowEnergyDevices.clear()
        // viewModel.scanLowEnergyDevices.value.clear()
    } 
    

    or in your use-case, since its wrap inside a State, just call the .value before the .add() and .clear() calls