Search code examples
androidkotlinandroid-jetpack-composekotlin-sharedflow

How do I get previous value from SharedFlow after Activity recreate/Configuration change in Jetpack Compose?


Suppose I have ScanActivity using jetpack compose that can scan Barcode, the result will shown in TextField and result will survive from configuration change(e.g screen rotation). I won't use StateFlow because after the result shown then I rotate my screen it will call API again, but the result become empty I want to keep the result.

ScanActivity:

class ScanActivity : BaseActivity(){

    private val scanViewModel: ScanViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
   
    setContent {
      val detectedBarcode by scanViewModel.detectedBarcode.collectAsState(initial = null)
    
     LaunchedEffect(detectedBarcode){                
    //API Call
    ...
    //
      scanViewModel.setBarcodeField(detectedBarcode?.rawValue ?: "")
    }
    
    MyTextField()

}}

ScanViewModel:

class ScanViewModel: ViewModel(){

    val detectedBarcode = MutableSharedFlow<Barcode>()
    val barcodeResultField = MutableLiveData<String>()

    fun setBarcodeField(barcode: String) {
        barcodeResultField.postValue(barcode)
    }
}

My TextField:

@Composable
fun MyTextField(scanViewModel: ScanViewModel = viewModel()){
    val barcode by scanViewModel.barcodeResultField.observeAsState("")
    TextField(value = barcode, onValueChange = {brc ->
            scanViewModel.setBarcodeField(brc)
        },
            label = {
                Text(text = "Barcode Field")
            })

}

Solution

  • Give your SharedFlow a replay amount of 1 so it replays the most recent emission to new subscribers.

    val detectedBarcode = MutableSharedFlow<Barcode>(replay = 1)