I hope to set _isRecording
inside SoundViewModel
class, and I hope to expose isRecording
to UI.
But the Code A is wrong, how can I fix it?
Code A
class SoundViewModel @Inject constructor(): ViewModel() {
private var _isRecording by mutableStateOf(false)
val isRecording: State<Boolean> by _isRecording //It's wrong
//val isRecording: State<Boolean> = _isRecording //It's wrong
..
}
Add content:
To nglauber: Thanks!
I think Code B will work well.
Which is better between your code and Code B?
Code B
class SoundViewModel @Inject constructor(): ViewModel() {
var isRecording by mutableStateOf(false)
private set
}
@Composable
fun YourComposable(soundViewModel: SoundViewModel) {
//I can use soundViewModel.isRecording directly
}
When you use the keyword by
, it's basically an alias to getValue
/setValue
. Therefore:
// _isRecording is a Boolean
private var _isRecording by mutableStateOf(false)
// _isRecording is a State<Boolean>
private var _isRecording = mutableStateOf(false)
This is why you're getting this error.
You should expose like this:
class SoundViewModel @Inject constructor(): ViewModel() {
private var _isRecording = mutableStateOf(false)
val isRecording: State<Boolean> = _isRecording
}
and consume like this:
@Composable
fun YourComposable(soundViewModel: SoundViewModel) {
val isRecording by soundViewModel.isRecording
CLEARLY -- Code B is the best option. That's exactly what official Compose Docs recommend. The method with the underscore was adopted for LiveData
objects, but when you shift to the Compose-compatible MutableState<T>
, it is simply de-efficiencizing(?) your code, if you add that extra underscore step.
Check out the State-in-Compose for full insights.
Go with the simplest approach that gets the job done, always the rule of thumb.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With