-
-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to create ViewModel in Jetpack Compose? #418
Comments
Is https://github.com/evant/kotlin-inject/blob/main/docs/android.md#viewmodels what you are looking at? The idea is you inject the function to create the viewmodel then call it in
To inject into something it needs to be part of the component graph yah. I believe in the doc I linked it shows injecting into the composable but you could inject it into the fragment/activity instead if you want to do it that way, or create the component in the activity/fragment access the viewmodel creation function from it and pass it as an argument yourself.
Not sure I understand, could you provide an example where it appears to leak memory?
When using compose your top-level composable function is often glue to wire your UI to your business logic, which is what fragments were traditionally used for. So I think it does make sense for them to be part of your graph.
Passing paramaters is done used assisted injection, the link shows an example using a @Inject
class MyViewModel(@Assisted private val myArg: Arg) : ViewModel()
...
@Component fun MyComponent(createMyViewModel: (Arg) -> MyViewModel) {
val viewModel = viewModel { createMyViewModel(arg) }
} |
Hi, I implemented it as follows. For your reference. I defined a factory class for NavGraphBuilder (Jetpack AndroidX Navigation) and distributed the ViewModel from there to Composable. interface AppRouteFactory {
fun NavGraphBuilder.create(
navController: NavController,
modifier: Modifier,
)
} Example: HomeScreen with HomeViewModel @Inject
class HomeRouteFactory(
private val viewModelFactory: () -> HomeViewModel,
) : AppRouteFactory {
override fun NavGraphBuilder.create(navController: NavController, modifier: Modifier) {
composable(route = "HOME_ROUTE") { _ ->
val viewModel = viewModel { viewModelFactory() }
/* @Composable HomeScreen here */
}
}
} Then I distributed this from a MainActivity Component(kotlin-inject) via AppContent. interface AppContent {
@Composable
fun Content(
modifier: Modifier,
)
}
@Inject
class AppContentImpl(
private val routeFactories: Set<AppRouteFactory>,
) : AppContent {
@Composable
override fun Content(
modifier: Modifier,
) {
NavHost(
navController = rememberNavController(),
startDestination = "HOME_ROUTE",
modifier = modifier,
) {
routeFactories.forEach { routeFactory ->
with(routeFactory) {
this@NavHost.create(
navController = navController,
modifier = Modifier,
)
}
}
}
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val applicationComponent = /* Call your ApplicationComponent. */
val component = MainActivityComponent::class.create(applicationComponent)
setContent {
component.appContent.Content(
modifier = Modifier,
)
}
}
} Here is the MainActivity Component. @Scope
annotation class MainActivityScope
@MainActivityScope
@Component
abstract class MainActivityComponent(
@Component val applicationComponent: ApplicationComponent,
) : UiComponent
interface UiComponent {
val appContent: AppContent
@MainActivityScope
@Provides
fun bindAppContent(bind: AppContentImpl): AppContent = bind
@IntoSet
@MainActivityScope
@Provides
fun bindHomeRouteFactory(bind: HomeRouteFactory): AppRouteFactory = bind
} Full code is here https://github.com/oikvpqya/qiita-kotlin-inject-sample |
Hello.
I'm trying to understand the documentation and can't find any important details.
How to create and pass a ViewModel in Jetpack Compose for Android?
The example I found suggests injecting the entire compose screen creation function directly into the component. But is that right? What about memory leaks and everything else? For me, it seems like some kind of reference to the view in the business logic of the application.
Also, passing parameters to such function is not sufficiently disclosed.
The text was updated successfully, but these errors were encountered: