hiltを使ってViewModelを画面間で引き継いで使う実装をしてみようと思います
NavigationGraphをネストさせてbackstackをhiltViewModel()に渡すことで実現できます
developerの説明
https://developer.android.com/jetpack/compose/libraries#hilt
hiltの依存関係の設定
いつも通りサクッと設定
[versions]
com-google-devtools-ksp = "1.9.20-1.0.14"
hilt = "2.50"
hiltNavigationCompose = "1.2.0-alpha01"
[libraries]
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
[plugins]
com-google-devtools-ksp = {id = "com.google.devtools.ksp", version.ref = "com-google-devtools-ksp" }
com-google-dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
plugins {
alias(libs.plugins.com.google.devtools.ksp) apply false
alias(libs.plugins.com.google.dagger.hilt.android) apply false
}
plugins {
alias(libs.plugins.com.google.devtools.ksp)
alias(libs.plugins.com.google.dagger.hilt.android)
}
dependencies {
implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.hilt.android)
ksp(libs.hilt.compiler)
}
hiltをプロジェクトに適応
いつも通りサクッと追加
/**
* ```AndroidManifest.xml
* <application
* android:name=".Application"
* ```
*/
@HiltAndroidApp
class Application : android.app.Application() {
override fun onCreate() {
super.onCreate()
}
}
@AndroidEntryPoint
class MainActivity : ComponentActivity() { ... }
実装
確認用のUIを用意
@HiltViewModel
class AppViewModel @Inject constructor() : ViewModel() {
var text = ""
}
@Composable
private fun Screen(
onClick: () -> Unit,
modifier: Modifier = Modifier,
text: String = "",
vm: AppViewModel = hiltViewModel()
) {
Column(modifier) {
Button(onClick = onClick) {
Text(vm.text + text)
}
}
}
@Composable
fun TopScreen(onClick: () -> Unit, vm: AppViewModel) = Screen(onClick, Modifier, "1", vm)
@Composable
fun NextScreen(onClick: () -> Unit, vm: AppViewModel) = Screen(onClick, Modifier, "2", vm)
Navgationを実装
TopScreenでViewModelに指定した”test”がNextScreenにも適応されていることが確認できます
hiltViewModel()にbackstackを渡さない場合は”test”は表示されないです
const val BaseRoute = "Base"
enum class NavDestination {
Top,
Next;
operator fun invoke() = name
}
fun NavGraphBuilder.navGraph(navController: NavController) {
navigation(startDestination = NavDestination.Top(), route = BaseRoute) {
NavDestination.entries.forEach { destination ->
composable(destination()) { backStackEntry ->
val parentEntry = remember(backStackEntry) {
navController.getBackStackEntry(BaseRoute)
}
val vm: AppViewModel = hiltViewModel(parentEntry)
// val vm: AppViewModel = hiltViewModel()
when (destination) {
NavDestination.Top -> {
vm.text = "test"
TopScreen(onClick = { navController.navigate(NavDestination.Next()) }, vm = vm)
}
NavDestination.Next -> NextScreen(onClick = { navController.popBackStack() }, vm = vm)
}
}
}
}
}
@Composable
fun AppContent() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = BaseRoute) {
navGraph(navController)
}
}
Android Studio Hedgehog 2023.1.1 Patch 1 built on December 27, 2023