I taught I was a master class native Android Developer until Jetpack Compose came along
@MrSN99 Жыл бұрын
Hm. Normally we would do it by having a "Content" composable, which takes the state and it allows us preview the "Content" only. That way the viewmodels aren't injected in the navigation, but instead in the screen composable, and the content gets the state.
@segunfrancis10 ай бұрын
We do the same thing
@jeky7794 ай бұрын
in Philipp's case viewmodel isn't injected in the navigation, it is inside "composable" funcrion of NavHost
@ПавелЯкунин-й5т Жыл бұрын
bro you literally learned me to do it like this in mvvm video!
@undeadredemption_6 ай бұрын
Hahahaha same here 😅
@Jeewanct7 ай бұрын
This is not a hard fast rule for the root compostable function view model can be passed in parameter it is just a single source of truth and pass down data to the lower composable function. This rule is correct for the lower composable function.
@jeanbourgarel1536 Жыл бұрын
Great tip and greatly explained, looking forward to get some more !!
@jeyhey532010 ай бұрын
I prefer to pass the view model to the view and have a flag in its constructor for instantiating it as a mock for testing.
@Chris1739726 ай бұрын
Almost like a isPreview parameter
@adrian110288 Жыл бұрын
Hi Philipp, can you advice how to handle events when you want to send them to the UI when you need a context, such as e.g on press of a button you want to open an Intent for mail app. I would handle a button click like you do here with viewModel:onEvent function but how I would send a action to the UI (if you do it via state object, do you have examples of how you model that). Much appreciated!
@arvindkumar72446 Жыл бұрын
You can declare a variable in UI State for example open mail and when you click the button update the ui state with open mail to true and trigger the intent in UI if open mail is true, if you understand it that's good if don't feel free to ask again.
@jeky7794 ай бұрын
events that are sent to the UI are called sideEffects, usually you first send an event like Phillip does in this video, then in a VM you have a channel or mutableSharedFlow, you pass an event "sideEffect" in this channel, which is collected on a ui screen
@haroldpepete2 ай бұрын
and if a child component needs that same state, you should do it in the same way, that looks really ugly, android needs to change this
@francismwangi6037 Жыл бұрын
I heard the same problem for quite some time, thank mahn
@Felix-3737 Жыл бұрын
so clean, love it!
@johnshepard1267 Жыл бұрын
Well, idk, looks wierd. In docs you read about hilt and how to provide it inside the screen, now you're not even allowed to use view model normally but to split it in state and functions. Kinda wierd what if you have so many of functions? I dont usually preview the entire screen but rather some functions.
@PhilippLackner Жыл бұрын
For previewing single functions that of course works if you expose callbacks and don't pass the ViewModel
@CorneliusJubril Жыл бұрын
can you show us the "HomeState" and "HomeEvent" class?
@thebatu Жыл бұрын
Hi, interesting! However, it looks like we could end up with a blotted navigation component?
@PhilippLackner Жыл бұрын
You can also put the code of the composable blocks in a separate composable as long as your actual screen content is viewmodel-free
@thebatu Жыл бұрын
@@PhilippLackner not sure if it is the responsibility of the navigation to instantiate a viewModel, navigation should just navigate imo...
@deepakbisht4957 Жыл бұрын
Who said it's the responsibility of the Navigation thing? But according to the Android team. Viewmodel should be present in screen level components and they should be created at that level too. Now it's up to you how exactly you are creating them. Using some kind of factory pattern, or using delegation or using dependency injection...
@도넛-e1r Жыл бұрын
Thank you!! So where can we collect a flow data?
@radu2173 Жыл бұрын
You dont need to preview screen level composables. You should use preview on miny pieces of the puzzle. Anyway you are hoisting the state down to these pieces so they dont have the viewmodel as parameter.
@FahadAyaz4 ай бұрын
I do both. I have previews for composable components but then I also preview what a screen looks like too. I actually already do pretty much what he just showed in the video and you can easily have multiple screen-level composable previews for different states eg empty state, a couple of items, many many items etc
@pattmehta5835 Жыл бұрын
nice, but if you start prototyping an actual home-screen you would need a view model 😊 this video holds true for unit testing navigation only not testing an api response that loads data to a view
@PhilippLackner Жыл бұрын
I don't get what you mean, you still use ViewModels with this approach, you just don't pass them directly to the screen compsable
@pattmehta5835 Жыл бұрын
@@PhilippLackner how can I make changes to that view and see live preview without vm if I don't want to launch it from another view - that was my use case
@SahilTheExplorer8 ай бұрын
You can create a route composable also
@HarisIqbal-y4y Жыл бұрын
Excellent, and is that the best way to add navigation composable on each composable screen on multi-module architecture?
@MobileAcademys Жыл бұрын
Cool ❤ what about the hiltViewModel does it solve the problem?
@PhilippLackner Жыл бұрын
No it doesn't. Hilt doesn't run for the preview
@MobileAcademys Жыл бұрын
@Philipp Lackner thanks 😊. At least it solves the testability
@mymobile550 Жыл бұрын
Saw this first time 🤔
@ikerluqup56612 ай бұрын
Thanks
@theevan3867 Жыл бұрын
guess i gotta edit some projects. thanks!
@kovshichek5933 Жыл бұрын
Can we make internal fun version of composable there we create val ViewModel and then call private fun of this composable to which we pass states and receive callbacks? Pretty much the same, but make nav more clean
@mymobile550 Жыл бұрын
I saw this in official compose samples 👍
@kovshichek5933 Жыл бұрын
@@mymobile550 do you have link?
@Synthwave89 Жыл бұрын
Why do we want to move over to compose again?
@warTag68 Жыл бұрын
Nice!
@seguramlk5 ай бұрын
Well, you just moved the dependency from one method to the other so you won't have to pass a VM to your preview but you just created a connection of another function to your VM and such method you also won't ne able to test in isolation because you'll need to create a static context for that VM you can't pass as a parameter
@jeky7794 ай бұрын
well, Philipp talked only about previews, what else do you want to test?
@sabaspravia Жыл бұрын
Do you have the whole code?
@talhafakoglu4680 Жыл бұрын
Hi Philipp, can we use the HomeRoute instead of Home Screen. We can injection viewmodel in HomeRoute and pass the UI state to HomeScreen. I think its better. Like nowinandroid.
@talhafakoglu4680 Жыл бұрын
Also we can use preview for HomeScreen and NavHost is so clean
@jenovas00 Жыл бұрын
Exactly how I do it, I have a "HomeScreen" and it's job is to get the ViewModel with hiltViewModel, get the states it needs, setup onEvent listeners and pass all of that to the "HomeContent" which is where the actual drawing happens. With this approach you have everything about the HomeScreen in one place and you don't need to search in your project where and what is being passed and it works in multimodule projects. I don't think what Philipp showed would be usable in multimodule projects, the navigation would need to know about every ViewModel for it to work.
@talhafakoglu4680 Жыл бұрын
@@jenovas00 yes definitely. so i don't like it
@imamyusupbachtiar5461 Жыл бұрын
@@jenovas00 did you have a repository for this case plaese ? i need more reference
@andrekelvin2318 Жыл бұрын
But what if the app don't need navigation, how can this be archived?
@walkmn Жыл бұрын
What is the `HomeState`? Interface? Could you please share the content of HomeState? And HomeEvent as well?
@ernestguevara5968 Жыл бұрын
It’s MVI, yeah interfaces
@sharzdin8402 Жыл бұрын
If there are many composables within HomeScreen, would I need to pass in more state to achieve my needs? Does this mean that HomeScreen's parameter list could have dozens or even hundreds of parameters? Would this be a good approach to coding?
@PhilippLackner Жыл бұрын
How often do you really need hundreds of parameters for a single screen? Sounds more like something very rare in which case you could of course split it up.
@vitaliisuslin5062 Жыл бұрын
I like to follow for all your topics and investigations. Thank you for that. So, in this case we have to use states in the compose screens and it means that all screens should have states and no dependencies of the viewmodel right? What can we do if we are trying to split screen components into different compose functions and want to update only one inside? Do we have to put down component state inside the general screen state? What do you think is better to do?
@PhilippLackner Жыл бұрын
Then you just pass the needed fields of your screen state to the composable
@vitaliisuslin5062 Жыл бұрын
@@PhilippLackner That means, one UI state for one screen with all needed fields for all components and compose will recompose only components with changes. Looks good. I saw the same approach with xml layouts. But we decided to split it into different streams and all of them have small components states. That's why I thought that we can use the same way in Compose.
@uop6238 Жыл бұрын
but nowinandroid does like that
@imamyusupbachtiar5461 Жыл бұрын
could you implement that in previous project like crypto currency series.?
@eagleclaww Жыл бұрын
Seems like you are forced to use MVI with compose otherwise you will get a million parameters and there is no clear solution for it. Compose is flawed because functions are supposed to do things, not be things. In SwiftUI structs are used for views which makes much more sense, and you can pass the view model and preview works.
@PhilippLackner Жыл бұрын
In SwiftUI you'll also need to provide an instance of a ViewModel to the preview, since the language can't magically know how it is created. In Compose we can do the exact same thing, but since instantiating a state is easier than a ViewModel, I prefer this approach I showed here
@victoreta Жыл бұрын
I like this approach, sadly for us, our ViewModels have several methods that the Composable should call. We can end sending 10+ onEvent lambda methods on the HomeScreen constructor.
@PhilippLackner Жыл бұрын
Why would you need 10 lambdas, you just need one - that's the whole point of this approach 😅
@victoreta Жыл бұрын
Hi@@PhilippLackner, thanks for answer. Maybe i wasn't clear about why our Compose needs more of 1 lambda or I am missing something. So, lets me try again in a basic example. Imagine a ViewModel that need to be informed when the user presses a reply button and if accept or cancel a dialog. If i understand correctly, for doing that we need to add 3 lambda functions to HomeScreen, one for reply, one for accept dialog and one for cancel the dialog..Am i missing something? :P
@PhilippLackner Жыл бұрын
@@victoreta no, you just call onEvent(YourEvent.ClickReply) or onEvent(YourEvent.DismissDialog). You can add as many events as you want and keep using one lambda
@victoreta Жыл бұрын
@PhilippLackner Got it now. I missed the HomeEvent part :D
@victoreta Жыл бұрын
What do you think about include the lambda methods in the UI state. Something like this: SplashUIState( isLoading: Boolean = isLoading, isError: String? = errorText onRetry = { doSomething() }, onAccepted = { doOtherThing()}, onCanceled = { doAdifferentThing()} ) I has the advantage that we don't need to create YourEvent. We will have only one solid connection between UI and ViewModel. Maybe it won't be a UI state anymore but the name can be changed.
@ikerluqup56612 ай бұрын
Can you share the code 😢? Please
@theevan3867 Жыл бұрын
how would you make a homestate?
@trandat2030 Жыл бұрын
Preview with hiltViewModel is working currently btw
@PhilippLackner Жыл бұрын
Until your viewmodel has injected dependencies 😄
@trandat2030 Жыл бұрын
@@PhilippLackner sorry my bad, I missed that one
@albab790 Жыл бұрын
thank you
@MohammadBilal51214 Жыл бұрын
What aboit koin viewmodel. As koin is runtime initialized. Then the preview does not build up. Do you have any solution for that.
@PhilippLackner Жыл бұрын
Same as any other type of ViewModel
@cleawrence Жыл бұрын
In one of your formation, u did that mistake.
@PhilippLackner Жыл бұрын
Because I also wasn't born with my Android knowledge, but learn over time :)
@cleawrence Жыл бұрын
@@PhilippLackner its okay bro WE are learning over and over