Home > Enterprise >  How can I know which the subclass of sealed class will return when I use Compose in Android Studio?
How can I know which the subclass of sealed class will return when I use Compose in Android Studio?

Time:03-30

The Result<out R> is a sealed class which hold three subclass Success, Error and Loading.

The fun Greeting is @Composable.

By my design, I define queryList as Result class, and it is assigned as Loading first, then it will be Success or Error.

1: But the following code can't be compiled as the following error information, what's wrong with my Code?

2: Is there a better solution for my design?

Compile error

Property delegate must have a 'getValue(Nothing?, KProperty>)' method. None of the following functions are suitable.*

@Composable
fun Greeting(
    name: String,
    mViewMode:SoundViewModel= viewModel()
) {
    Column() {
       //The following code cause error.  
       val queryList by produceState(initialValue = Result<Flow<List<MRecord>>>.Loading ) {
          value = mViewMode.listRecord()
       }

       when (queryList){
          is Loading -> { ...}
          is Error  -> { ...}
          is Success -> {...}
       }

    }
}       

class SoundViewModel @Inject constructor(): ViewModel()
{
    fun listRecord(): Result<Flow<List<MRecord>>>{
        return  aSoundMeter.listRecord()
    }

}
    
sealed class Result<out R> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

CodePudding user response:

Since queryList is backed by a delegate, it can not be final.
This means in theory, each time you access it, it might hold a different value. The kotlin compiler is very pessimistic about this and assumes that between the time the is Result.Success branch of your when statement is selected and val mydata = queryList.data is executed, the value of queryList might have changed.

To solve this, you can assign the current value of queryList to a final variable and work with that one instead:

when (val currentList = queryList) {
    is Result.Error -> {}
    is Result.Loading -> {}
    is Result.Success -> {
        SomeComposable(currentList.data) //currentList is properly smart-cast to Result.Success
    }
}

  • Related