KotlinLeaner
02/09/2024, 6:14 PMkoinViewModel()
to get instance of viewModel. I recently saw a Koin Documentation have separate koin-androidx-compose-navigation
which gives a koinNavViewModel()
function.KotlinLeaner
02/09/2024, 6:14 PMdependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("io.insert-koin:koin-android:3.4.0")
implementation("io.insert-koin:koin-androidx-workmanager:3.4.0")
implementation("io.insert-koin:koin-androidx-compose:3.4.6")
implementation("io.insert-koin:koin-androidx-compose-navigation:3.4.6")
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.foundation:foundation-layout")
implementation("androidx.compose.material:material")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.runtime:runtime")
implementation("androidx.compose.runtime:runtime-livedata")
implementation("androidx.compose.ui:ui-tooling")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:$2.6.2")
implementation("androidx.navigation:navigation-compose:$2.6.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
KotlinLeaner
02/12/2024, 3:24 PMSharedFlow
and navigate to another screen with same viewmodel instance it gives me variable null
.
MainActivity.kt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SimpleComposeNavigationTheme {
SimpleNavigation()
}
}
}
}
SimpleNavigation
@Composable
fun SimpleNavigation(navController: NavHostController = rememberNavController()) {
NavHost(
navController = navController,
startDestination = navController.currentBackStackEntry?.destination?.route ?: "first_screen"
) {
composable("first_screen") {
val viewModel: FirstViewModel = koinNavViewModel()
Surface {
Column(Modifier.fillMaxSize()) {
Button(onClick = { viewModel.updateName("Hello world") }) {
Text(text = "Add Name")
}
Button(onClick = { navController.navigate("second_screen") }) {
Text(text = "Next Screen")
}
}
}
}
composable("second_screen") {
val viewModel: FirstViewModel = koinNavViewModel()
val firstName by viewModel.firstName.collectAsState()
LaunchedEffect(firstName){
println(">> $firstName")
}
Surface {
Column(Modifier.fillMaxSize()) {
firstName?.let { name -> Text(text = name) }
}
}
}
}
}
FirstViewModel.kt
class FirstViewModel : ViewModel() {
private val _firstName = MutableSharedFlow<String?>()
val firstName: SharedFlow<String?> = _firstName.asSharedFlow()
fun updateName(name: String) {
viewModelScope.launch {
_firstName.emit(name)
}
}
}
What is the benefits of using koinNavViewModel()
if we cannot share the same instance in different screens of compose through navigation?KotlinLeaner
02/12/2024, 3:26 PMclass SampleApplication : Application() {
override fun onCreate() {
super.onCreate()
initializeDependencyInjection()
}
private fun initializeDependencyInjection() {
startKoin {
androidLogger(Level.ERROR)
modules(
listOf(simpleModule)
)
}
}
}
val simpleModule = module {
viewModelOf(::FirstViewModel)
}
Stylianos Gakis
02/12/2024, 3:37 PMkoinNavViewModel
is just "koinViewModel" but automatically passes the arguments passed to the destination as shown here https://github.com/InsertKoinIO/koin/blob/main/projects%2Fcompose%2Fkoin-androidx-compose-navigation%2Fsrc%2Fmain%2Fjava%2Forg%2Fkoin%2Fandroidx%2Fcompose%2Fnavigation%2FNavViewModelInternals.kt#L39
We just use koinViewModel() itself which automatically uses the current nav route lifecycle, and if we want to scope it higher we do it like here https://github.com/HedvigInsurance/android/blob/develop/app%2Fnavigation%2Fnavigation-compose-typed%2Fsrc%2Fmain%2Fkotlin%2Fcom%2Fhedvig%2Fandroid%2Fnavigation%2Fcompose%2Ftyped%2FDestinationScopedViewModel.kt#L16-L25 by using that higher destination as the viewModelStoreOwnerStylianos Gakis
02/12/2024, 3:38 PMKotlinLeaner
02/12/2024, 3:46 PMStylianos Gakis
02/12/2024, 8:09 PM