Skip to content

Commit 4790b17

Browse files
Work with koin-compose-navigation3 directly
1 parent c30e847 commit 4790b17

File tree

7 files changed

+22
-96
lines changed

7 files changed

+22
-96
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ dependencies {
8585
implementation(libs.hilt.android)
8686
ksp(libs.hilt.compiler)
8787
implementation(libs.koin.compose.viewmodel)
88+
implementation(libs.koin.navigation3)
8889

8990
testImplementation(libs.junit)
9091
androidTestImplementation(libs.androidx.junit)
Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,14 @@
11
package com.example.nav3recipes.modular.koin
22

3-
import androidx.compose.runtime.Composable
4-
import androidx.navigation3.runtime.entry
5-
import com.example.nav3recipes.modular.hilt.EntryProviderInstaller
6-
import org.koin.core.annotation.KoinInternalApi
7-
import org.koin.core.definition.KoinDefinition
8-
import org.koin.core.module.KoinDslMarker
9-
import org.koin.core.module.Module
10-
import org.koin.core.module._scopedInstanceFactory
11-
import org.koin.core.module._singleInstanceFactory
12-
import org.koin.core.qualifier.named
13-
import org.koin.core.scope.Scope
14-
import org.koin.dsl.ScopeDSL
3+
import org.koin.androidx.scope.dsl.activityRetainedScope
154
import org.koin.dsl.module
165

176
val appModule = module {
187
includes(profileModule,conversationModule)
198

20-
scope<KoinModularActivity> {
9+
activityRetainedScope {
2110
scoped {
2211
Navigator(startDestination = ConversationList)
2312
}
2413
}
25-
}
26-
27-
@KoinDslMarker
28-
fun Scope.navigator(): Navigator = get<Navigator>()
29-
30-
//TODO Need typealias EntryProviderInstaller = EntryProviderBuilder<Any>.() -> Unit-
31-
32-
@KoinDslMarker
33-
@OptIn(KoinInternalApi::class)
34-
inline fun <reified T : Any> ScopeDSL.navigation(
35-
noinline definition: @Composable Scope.(T) -> Unit,
36-
): KoinDefinition<EntryProviderInstaller> {
37-
val def = _scopedInstanceFactory<EntryProviderInstaller>(named<T>(), {
38-
val scope = this
39-
{
40-
entry<T>(content = {definition(scope,it)})
41-
}
42-
}, scopeQualifier)
43-
module.indexPrimaryType(def)
44-
return KoinDefinition(module, def)
45-
}
46-
47-
@KoinDslMarker
48-
@OptIn(KoinInternalApi::class)
49-
inline fun <reified T : Any> Module.navigation(
50-
noinline definition: @Composable Scope.(T) -> Unit,
51-
): KoinDefinition<EntryProviderInstaller> {
52-
val def = _singleInstanceFactory<EntryProviderInstaller>(named<T>(), {
53-
val scope = this
54-
{
55-
entry<T>(content = {definition(scope,it)})
56-
}
57-
})
58-
indexPrimaryType(def)
59-
return KoinDefinition(this, def)
6014
}

app/src/main/java/com/example/nav3recipes/modular/koin/CommonModule.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ package com.example.nav3recipes.modular.koin
22

33
import androidx.compose.runtime.mutableStateListOf
44
import androidx.compose.runtime.snapshots.SnapshotStateList
5-
import androidx.navigation3.runtime.EntryProviderBuilder
6-
import dagger.hilt.android.scopes.ActivityRetainedScoped
7-
import javax.inject.Inject
8-
9-
10-
typealias EntryProviderInstaller = EntryProviderBuilder<Any>.() -> Unit
115

126
class Navigator(startDestination: Any) {
137
val backStack : SnapshotStateList<Any> = mutableStateListOf(startDestination)

app/src/main/java/com/example/nav3recipes/modular/koin/ConversationModule.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ import androidx.compose.ui.Modifier
2121
import androidx.compose.ui.graphics.Color
2222
import androidx.compose.ui.unit.dp
2323
import com.example.nav3recipes.ui.theme.colors
24+
import org.koin.androidx.scope.dsl.activityRetainedScope
25+
import org.koin.core.annotation.KoinExperimentalAPI
2426
import org.koin.dsl.module
27+
import org.koin.dsl.navigation3.navigation
2528

2629
// API
2730
object ConversationList
@@ -30,19 +33,20 @@ data class ConversationDetail(val id: Int) {
3033
get() = colors[id % colors.size]
3134
}
3235

36+
@OptIn(KoinExperimentalAPI::class)
3337
val conversationModule = module {
34-
scope<KoinModularActivity> {
38+
activityRetainedScope {
3539
navigation<ConversationList> {
3640
ConversationListScreen(
3741
onConversationClicked = { conversationDetail ->
38-
navigator().goTo(conversationDetail)
42+
get<Navigator>().goTo(conversationDetail)
3943
}
4044
)
4145
}
4246

4347
navigation<ConversationDetail> { key ->
4448
ConversationDetailScreen(key) {
45-
navigator().goTo(com.example.nav3recipes.modular.koin.Profile)
49+
get<Navigator>().goTo(Profile)
4650
}
4751
}
4852
}

app/src/main/java/com/example/nav3recipes/modular/koin/KoinModularActivity.kt

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,21 @@
11
package com.example.nav3recipes.modular.koin
22

3-
import android.content.ComponentCallbacks
43
import android.os.Bundle
54
import androidx.activity.ComponentActivity
65
import androidx.activity.compose.setContent
76
import androidx.compose.foundation.layout.padding
87
import androidx.compose.material3.Scaffold
98
import androidx.compose.ui.Modifier
10-
import androidx.navigation3.runtime.NavEntry
11-
import androidx.navigation3.runtime.entryProvider
129
import androidx.navigation3.ui.NavDisplay
13-
import com.example.nav3recipes.modular.hilt.EntryProviderInstaller
1410
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
15-
import org.koin.android.ext.android.get
16-
import org.koin.android.ext.android.getKoin
17-
import org.koin.android.ext.android.getKoinScope
1811
import org.koin.android.ext.android.inject
1912
import org.koin.android.ext.koin.androidContext
2013
import org.koin.android.scope.AndroidScopeComponent
14+
import org.koin.androidx.compose.navigation3.getEntryProvider
2115
import org.koin.androidx.scope.activityRetainedScope
22-
import org.koin.compose.getKoin
23-
import org.koin.core.annotation.KoinInternalApi
16+
import org.koin.core.annotation.KoinExperimentalAPI
2417
import org.koin.core.context.startKoin
2518
import org.koin.core.context.stopKoin
26-
import org.koin.core.parameter.ParametersDefinition
27-
import org.koin.core.qualifier.Qualifier
2819
import org.koin.core.scope.Scope
2920
import org.koin.mp.KoinPlatform
3021

@@ -42,28 +33,7 @@ import org.koin.mp.KoinPlatform
4233
* The app module creates the navigator by supplying a start destination and provides this navigator
4334
* to the rest of the app module (i.e. MainActivity) and the feature modules.
4435
*/
45-
46-
typealias EntryProvider = (Any) -> NavEntry<Any>
47-
48-
@OptIn(KoinInternalApi::class)
49-
inline fun ComponentCallbacks.entryProvider(
50-
mode: LazyThreadSafetyMode = LazyThreadSafetyMode.SYNCHRONIZED,
51-
) : Lazy<EntryProvider> = lazy(mode) { val entries = getKoinScope().getAll<EntryProviderInstaller>()
52-
val entryProvider: (Any) -> NavEntry<Any> = entryProvider {
53-
entries.forEach { builder -> this.builder() }
54-
}
55-
entryProvider
56-
}
57-
58-
@OptIn(KoinInternalApi::class)
59-
inline fun ComponentCallbacks.getEntryProvider() : EntryProvider {
60-
val entries = getKoinScope().getAll<EntryProviderInstaller>()
61-
val entryProvider: (Any) -> NavEntry<Any> = entryProvider {
62-
entries.forEach { builder -> this.builder() }
63-
}
64-
return entryProvider
65-
}
66-
36+
@OptIn(KoinExperimentalAPI::class)
6737
class KoinModularActivity : ComponentActivity(), AndroidScopeComponent {
6838

6939
override val scope : Scope by activityRetainedScope()

app/src/main/java/com/example/nav3recipes/modular/koin/ProfileModule.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ import androidx.compose.runtime.Composable
1111
import androidx.compose.ui.Alignment
1212
import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.unit.dp
14+
import org.koin.androidx.scope.dsl.activityRetainedScope
15+
import org.koin.core.annotation.KoinExperimentalAPI
1416
import org.koin.dsl.module
17+
import org.koin.dsl.navigation3.navigation
1518

1619
// API
1720
object Profile
1821

22+
@OptIn(KoinExperimentalAPI::class)
1923
val profileModule = module {
20-
scope<KoinModularActivity> {
21-
navigation<Profile> {
22-
ProfileScreen()
23-
}
24+
activityRetainedScope {
25+
navigation<Profile> { ProfileScreen() }
2426
}
2527
}
2628

gradle/libs.versions.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ lifecycleViewmodel = "1.0.0-alpha04"
2626
activityCompose = "1.12.0-alpha09"
2727
composeBom = "2025.09.01"
2828
navigation2 = "2.9.1"
29-
navigation3 = "1.0.0-alpha11"
29+
navigation3 = "1.0.0-beta01"
3030
material3 = "1.4.0"
3131
nav3Material = "1.3.0-alpha01"
3232
ksp = "2.2.10-2.0.2"
3333
hilt = "2.57.1"
3434
hiltNavigationCompose = "1.3.0"
35-
koin = "4.1.1"
35+
koin = "4.2.0-alpha1"
3636

3737
[libraries]
3838
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -63,6 +63,7 @@ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serializa
6363
androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
6464
androidx-material3-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "nav3Material" }
6565
koin-compose-viewmodel = {group = "io.insert-koin", name = "koin-compose-viewmodel", version.ref = "koin"}
66+
koin-navigation3 = {group = "io.insert-koin", name = "koin-compose-navigation3", version.ref = "koin"}
6667

6768
[plugins]
6869
android-application = { id = "com.android.application", version.ref = "agp" }

0 commit comments

Comments
 (0)