julioromano
11/04/2021, 3:33 PMhiltViewModel()
is the only “easy” way to get dagger-managed objects from within a @Composable
function. Are there any alternatives?
2) In a non 100% compose app (where we can’t just disable all configuration changes in the manifest) any operation running inside a rememberCoroutineScope()
will be interrupted during a configuration change. In these cases we need to resort to the `ViewModel`’s viewModelScope
. Are there any alternatives?
Any insight on the topic is very much appreciated!Zach Klippenstein (he/him) [MOD]
11/04/2021, 4:34 PMjim
11/04/2021, 4:36 PMcurioustechizen
11/04/2021, 4:53 PMdrawerState.open()
)? I'm doing this inside my Composables. Moving the drawerState to something like a ViewModel is one option but it doesn't feel right for mixed Compose and android View appsjim
11/04/2021, 5:02 PMrememberCoroutineScope()
for things which are UI related and not long lived like that. You grab the coroutine scope up near where the drawer lives, and use it in the callback that is passed down to your button (both because that's the correct data flow, and also to ensure the coroutine has the correct lifetime and isn't running for longer/shorter than the drawer lives).curioustechizen
11/04/2021, 5:06 PMMarko Novakovic
11/04/2021, 5:52 PMCompose
and DI being bad. yet… everybody uses AAC ViewModel
and Hilt
. when I asked “are `ViewModel`s needed” everyone replied on that thread with “yes. they are not to be dropped yet” so am a bit confused. it’s not that hard to avoid ViewModel
, when I think about it, but I haven’t tried it in anything but simple examples to see how it works out. can any of you link to some examples that uses custom `ViewModel`s and no DI framework (passing dependencies as parameters, always) so we (I) can see how that plays out and how that looks like in real project? how does it scale, what are the major problems with it etc. it’s easier with examplesColton Idle
11/04/2021, 7:33 PMjim
11/04/2021, 7:37 PMZach Klippenstein (he/him) [MOD]
11/04/2021, 7:38 PMMarko Novakovic
11/04/2021, 9:08 PMMarko Novakovic
11/04/2021, 9:08 PMMarko Novakovic
11/04/2021, 9:10 PMNavHost
I create ViewModel
and I pass just state and lambdas to screensjulioromano
11/05/2021, 4:09 PMViewModel
via hiltViewModel()
just as a shortcut to tap into Hilt to get dependencies. My viewmodels are empty classes with only dependencies provided by Hilt as properties.
Each screen composable (i.e. the root composable of each navigation destination) gets its own viewmodel calling hiltViewModel()
, dependencies are then passed down the composable hierarchy as usual. The idea was to use a “wrapper composable” around the actual “screen composable” as the “entry point” that taps into Hilt.
To give you a rough idea:
@HiltViewModel
class MyScreenViewModel @Inject constructor(
val stuff: stuff
) : ViewModel()
/**
* Just a wrapper around the actual screen composable to keep the platform dependency "isolated".
*/
@Composable
fun MyScreenWrapper() {
val vm = hiltViewModel<MyScreenViewModel>()
MyScreen(stuff = vm.stuff)
}
/**
* This is the actual screen composable which is not tied to the platform.
*/
@Composable
fun MyScreen(stuff: Stuff) {
// Here the actual UI is built using reusable composable components.
}
I could delete the viewmodels and the screen wrappers: this will untie my composables from the Android platform, but then the only place remaining where I can tap into Hilt is MainActivity
. This means I’ll have to make MainActivity
as the “single point of injection” with Hilt and grab all dependencies from there.
My initial gut feeling was that I’ll end up with too many @Inject
lines inside `MainActivity`: Would this scale with lots of screens?
Now the more I think of it the more I think this is not a bad idea at all and that there are easy solutions to the “too many @Inject
lines” problem.
What do you think?jim
11/05/2021, 4:12 PMjulioromano
11/09/2021, 6:45 PM