nilTheDev
09/27/2021, 5:29 PMclass HelloViewModel : ViewModel() {
// LiveData holds state which is observed by the UI
// (state flows down from ViewModel)
private val _name = MutableLiveData("")
val name: LiveData<String> = _name
// onNameChange is an event we're defining that the UI can invoke
// (events flow up from UI)
fun onNameChange(newName: String) {
_name.value = newName
}
}
@Composable
fun HelloScreen(helloViewModel: HelloViewModel = viewModel()) {
// by default, viewModel() follows the Lifecycle as the Activity or Fragment
// that calls HelloScreen(). This lifecycle can be modified by callers of HelloScreen.
// name is the current value of [helloViewModel.name]
// with an initial value of ""
val name: String by helloViewModel.name.observeAsState("")
HelloContent(name = name, onNameChange = { helloViewModel.onNameChange(it) })
}
@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "Hello, $name",
modifier = Modifier.padding(bottom = 8.dp),
style = MaterialTheme.typography.h5
)
OutlinedTextField(
value = name,
onValueChange = onNameChange,
label = { Text("Name") }
)
}
}
However I couldn't use it on my environment. Particularly, this line of code fun HelloScreen(helloViewModel: HelloViewModel = viewModel())
is where the problem lies. My IDE isn't able to identify the viewModel()
function here. Where is it coming from? Do I need any other dependency to make it work?Ian Lake
09/27/2021, 5:32 PMlifecycle-viewmodel-compose
artifact is part of androidx.lifecycle
- you'll want to specifically include it: https://developer.android.com/jetpack/compose/libraries#viewmodelIan Lake
09/27/2021, 5:32 PMviewModel()
within a composable destination by default; there's nothing you need to do there to have that just workIan Lake
09/27/2021, 5:34 PMnilTheDev
09/27/2021, 5:51 PMnilTheDev
09/27/2021, 8:04 PMDaniele Segato
09/28/2021, 8:45 AMAnd if you're using Navigation Compose (https://developer.android.com/jetpack/compose/navigation), then ViewModels will already be scoped to each individual screens when you useas far as I know you cannot callwithin a composable destination by default; there's nothing you need to do there to have that just workviewModel()
viewModel()
from outside a Fragment or an Activity, this is not clearly stated in the documentation.
It's another story for hiltViewModel()
which I believe can be used anywhere.
I'm referring to this https://developer.android.com/jetpack/compose/librariesnilTheDev
09/28/2021, 9:49 AMviewModel()
function that comes with lifecycle-compose-viewmodel
artifact? I tried it yesterday and it worked perfectly. You can call the viewModel()
function in any composable. And as Ian said it would be scoped to the closest viewModelStoreOwner
i.e an activity or fragment. Check out this page https://developer.android.com/jetpack/compose/libraries#viewmodel and the video Ian shared in this thread.
In case you are talking about the viewModels()
delegate that initializes a viewModel lazily then, yes you can't access this outside of an activity or fragment.nilTheDev
09/28/2021, 9:52 AMviewModel()
inside any composable.Daniele Segato
09/28/2021, 10:13 AMlifecycle-compose-viewmodel
artifact, only the hiltViewModel()
or the delegate.
I'm a moderator in the Discord AndroidDev community and I've seen many people confused because viewModel()
wasn't working outside of the activity / fragment.
There's some confusion around that caused by the same name probably.nilTheDev
09/28/2021, 10:16 AMviewModels()
and the other one used with composable is viewModel()