Skip to content

Commit a2801c4

Browse files
committed
ui: use navigation3
So much simpler :-) Fixes #12
1 parent c633d5c commit a2801c4

32 files changed

Lines changed: 200 additions & 298 deletions

File tree

app/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ dependencies {
4141
implementation(project(":features:library:ui"))
4242
implementation(project(":features:overview:ui"))
4343
implementation(project(":theme"))
44+
implementation(libs.androidx.lifecycle.viewmodel.navigation3)
45+
implementation(libs.androidx.navigation3.ui)
46+
implementation(libs.androidx.navigation3.runtime)
4447
implementation(libs.coil.compose)
4548
implementation(libs.coil.network)
4649
implementation(libs.okhttp)

app/src/main/java/org/mrlem/composesample/MainNavBar.kt

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,30 @@ import androidx.compose.material3.NavigationBar
55
import androidx.compose.material3.NavigationBarItem
66
import androidx.compose.material3.Text
77
import androidx.compose.runtime.Composable
8-
import androidx.compose.runtime.getValue
98
import androidx.compose.ui.Modifier
109
import androidx.compose.ui.res.stringResource
11-
import androidx.navigation.NavController
12-
import androidx.navigation.compose.currentBackStackEntryAsState
13-
import org.mrlem.android.core.feature.nav.belongsTo
10+
import androidx.navigation3.runtime.NavBackStack
11+
import androidx.navigation3.runtime.NavKey
12+
import org.mrlem.android.core.feature.nav.Navigator
13+
import org.mrlem.android.core.feature.nav.Navigator.Operation
1414
import org.mrlem.android.core.feature.ui.NavProvider
1515

1616
@Composable
1717
fun MainNavBar(
1818
items: List<NavProvider.BottomBarItem>,
19-
navController: NavController,
19+
backStack: NavBackStack<NavKey>,
20+
navigator: Navigator,
2021
modifier: Modifier = Modifier,
2122
) {
2223
NavigationBar(
2324
modifier = modifier,
2425
) {
25-
val navBackStackEntry by navController.currentBackStackEntryAsState()
26-
val currentDestination = navBackStackEntry?.destination
27-
2826
items.forEach { item ->
2927
NavigationBarItem(
3028
icon = { Icon(item.icon, contentDescription = null) },
3129
label = { Text(stringResource(item.labelResId)) },
32-
selected = currentDestination?.belongsTo(item.route) ?: false,
33-
onClick = {
34-
navController.navigate(item.route) {
35-
popUpTo(0)
36-
launchSingleTop = true
37-
}
38-
},
30+
selected = backStack.firstOrNull() == item.key,
31+
onClick = { navigator.navigate(Operation.ReplaceAll(item.key)) },
3932
)
4033
}
4134
}
Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package org.mrlem.composesample
22

33
import androidx.compose.foundation.layout.imePadding
4-
import androidx.compose.foundation.layout.padding
4+
import androidx.compose.foundation.layout.systemBarsPadding
55
import androidx.compose.material3.Scaffold
66
import androidx.compose.material3.SnackbarHost
77
import androidx.compose.material3.SnackbarHostState
88
import androidx.compose.runtime.Composable
99
import androidx.compose.runtime.remember
1010
import androidx.compose.ui.Modifier
11-
import androidx.navigation.compose.NavHost
12-
import androidx.navigation.compose.rememberNavController
11+
import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
12+
import androidx.navigation3.runtime.entryProvider
13+
import androidx.navigation3.runtime.rememberNavBackStack
14+
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
15+
import androidx.navigation3.ui.NavDisplay
1316
import org.mrlem.android.core.feature.nav.NavigationLaunchedEffect
1417
import org.mrlem.android.core.feature.nav.Navigator
1518
import org.mrlem.android.core.feature.ui.NavProvider
@@ -19,42 +22,43 @@ fun MainWindow(
1922
navProviders: Set<NavProvider>,
2023
navigator: Navigator,
2124
) {
22-
val navController = rememberNavController()
25+
val backStack = rememberNavBackStack(navProviders.firstNotNullOf { it.startKey })
26+
2327
val items = navProviders
2428
.mapNotNull { it.navBarItem }
2529
.sortedBy { it.index }
2630
val snackbarHostState = remember { SnackbarHostState() }
2731

2832
NavigationLaunchedEffect(
2933
navigator = navigator,
30-
navController = navController,
34+
backStack = backStack,
3135
)
3236

3337
Scaffold(
3438
snackbarHost = { SnackbarHost(snackbarHostState) },
3539
bottomBar = {
3640
MainNavBar(
3741
items = items,
38-
navController = navController,
42+
navigator = navigator,
43+
backStack = backStack,
3944
modifier = Modifier
40-
.imePadding(),
45+
.imePadding()
46+
.systemBarsPadding(),
4147
)
4248
},
4349
) { innerPadding ->
44-
NavHost(
45-
navController = navController,
46-
startDestination = navProviders.firstNotNullOfOrNull { it.startRoute }
47-
?: throw IllegalArgumentException("no start destination defined"),
48-
modifier = Modifier
49-
.padding(innerPadding),
50-
) {
51-
navProviders.forEach { subGraph ->
52-
subGraph.graph(
53-
builder = this,
54-
snackbarHostState = snackbarHostState,
55-
innerPadding = innerPadding,
56-
)
57-
}
58-
}
50+
NavDisplay(
51+
backStack = backStack,
52+
onBack = { backStack.removeLastOrNull() },
53+
entryDecorators = listOf(
54+
rememberSaveableStateHolderNavEntryDecorator(),
55+
rememberViewModelStoreNavEntryDecorator(),
56+
),
57+
entryProvider = entryProvider {
58+
navProviders.forEach {
59+
it.entryBuilders.invoke(this, snackbarHostState, innerPadding)
60+
}
61+
},
62+
)
5963
}
6064
}

app/src/main/java/org/mrlem/composesample/di/MainModule.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ import javax.inject.Singleton
1515
@InstallIn(SingletonComponent::class)
1616
class MainModule {
1717

18-
private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
18+
private val applicationScope = CoroutineScope(context = SupervisorJob() + Dispatchers.Default)
1919

2020
@Singleton
2121
@Provides
22-
fun provideNavigator() = Navigator()
22+
@ApplicationScope
23+
fun provideApplicationScope() =
24+
applicationScope
2325

2426
@Singleton
2527
@Provides
26-
@ApplicationScope
27-
fun provideApplicationScope() = applicationScope
28+
fun provideNavigator() =
29+
Navigator(scope = applicationScope)
2830
}

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plugins {
1111
alias(libs.plugins.app.scripts)
1212
alias(libs.plugins.detekt) apply false
1313
alias(libs.plugins.ktlint) apply false
14+
alias(libs.plugins.serialization) apply false
1415
}
1516

1617
subprojects {

core/feature/nav/build.gradle.kts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ android {
88
}
99

1010
dependencies {
11-
implementation(libs.androidx.navigation)
11+
implementation(libs.androidx.navigation3.ui)
12+
implementation(libs.androidx.navigation3.runtime)
1213
}

core/feature/nav/src/main/java/org/mrlem/android/core/feature/nav/Destination.kt

Lines changed: 0 additions & 15 deletions
This file was deleted.

core/feature/nav/src/main/java/org/mrlem/android/core/feature/nav/DestinationDefinition.kt

Lines changed: 0 additions & 11 deletions
This file was deleted.

core/feature/nav/src/main/java/org/mrlem/android/core/feature/nav/NavControllerExt.kt

Lines changed: 0 additions & 9 deletions
This file was deleted.

core/feature/nav/src/main/java/org/mrlem/android/core/feature/nav/NavDestinationExt.kt

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)