<https://youtu.be/Gi-MnWDRcmQ> In this video Mitc...
# compose
n

https://youtu.be/Gi-MnWDRcmQ

In this video Mitch says there is no way to have a viewModel scoped to the lifecycle of a composable. So, he would use fragments to architect applications. The video is from 2020 so I was wondering whether Jetpack Compose has found any way out of this. This code snippet from the page https://developer.android.com/jetpack/compose/state seems useful here.
Copy code
class 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?
🧵 2
i
The
lifecycle-viewmodel-compose
artifact is part of
androidx.lifecycle
- you'll want to specifically include it: https://developer.android.com/jetpack/compose/libraries#viewmodel
And 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 use
viewModel()
within a composable destination by default; there's nothing you need to do there to have that just work
That's been the case since the first Navigation Compose alpha back in October 2020
n
@Ian Lake Thanks. It worked. 😃 I think I have to give a read to that part of the documentation where it talks about integrating other Jetpack libraries with compose.
i
We did a whole video on exactly that topic in fact:

https://www.youtube.com/watch?v=0z_dwBGQQWQ

👍 3
❤️ 2
n
@Ian Lake Watched that. Super helpful. Although I am a beginner and don't understand dependency injection. But the way viewModels are used in Compose is super cool.
d
@Ian Lake
And 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 use 
viewModel()
 within a composable destination by default; there's nothing you need to do there to have that just work
as far as I know you cannot call
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/libraries
n
@Daniele Segato Are you sure you are talking about the
viewModel()
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.
@Daniele Segato And the reference you linked clearly states you can indeed use
viewModel()
inside any composable.
d
I see, I never used the
lifecycle-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.
n
@Daniele Segato I think the name is similar but not the same. The delegate is
viewModels()
and the other one used with composable is
viewModel()
👍 1