Nav3Sample/
├── libraries/navigation ✅ Abstrakcja nawigacji (niezależna od frameworka)
│ ├── Route.kt - Interface NavKey
│ ├── NavAction.kt - Sealed class akcji nawigacji
│ ├── NavActionsEmitter.kt - Channel-based emiter
│ ├── NavActionsEffect.kt - Composable obserwujący akcje
│ └── AppNavigator.kt - Wrapper na NavBackStack
│
├── core/
│ ├── domain/ ✅ Modele, interfejsy, use case'y
│ │ ├── model/Order.kt
│ │ ├── repository/OrderRepository.kt
│ │ ├── usecase/GetOrdersUseCase.kt
│ │ ├── usecase/GetOrderByIdUseCase.kt
│ │ └── constants/AppConfig.kt
│ │
│ └── data/ ✅ Implementacje
│ └── repository/OrderRepositoryImpl.kt (z mock danymi)
│
├── features/order/ ✅ MVI pattern
│ └── presentation/
│ ├── OrderListContract.kt (State/Intent/Effect)
│ ├── OrderListViewModel.kt
│ ├── OrderDetailContract.kt
│ └── OrderDetailViewModel.kt
│
├── compose/order/ ✅ Ekrany Compose
│ ├── OrderListScreen.kt
│ └── OrderDetailScreen.kt
│
└── app/ ✅ Integracja
├── di/AppModule.kt - Koin DI
├── navigation/
│ ├── routes/ - OrderListRoute, OrderDetailRoute, AddOrderRoute
│ └── AppNavGraph.kt - Graf nawigacji
├── constants/AppConfigImpl.kt
├── App.kt - Application z Koin
└── MainActivity.kt - Entry point
interface AppNavigator {
val backStack: AppBackStack
fun navigateTo(route: Route)
fun navigateUp()
fun popBackTo(route: Route, inclusive: Boolean)
}// State
data class OrderListState(
val orders: List<Order>,
val isLoading: Boolean,
val error: String?
)
// Intent
sealed interface OrderListIntent {
data object LoadOrders : OrderListIntent
data class OnOrderClick(val orderId: String) : OrderListIntent
}
// Effect
sealed interface OrderListEffect {
data class NavigateToOrderDetail(val orderId: String) : OrderListEffect
}@Serializable
data object OrderListRoute : Route
@Serializable
data class OrderDetailRoute(val orderId: String) : Routeval appModule = module {
single<OrderRepository> { OrderRepositoryImpl() }
factory { GetOrdersUseCase(get()) }
factory { NavActionsEmitter() }
viewModel { OrderListViewModel(get(), get()) }
}val backStack = rememberNavBackStack(OrderListRoute)
val navigator = Nav3AppNavigator(backStack)
// Nawigacja przez dodawanie do listy
navigator.navigateTo(OrderDetailRoute(orderId))
// Cofanie przez usuwanie z listy
navigator.navigateUp()- ✅ Kotlin 2.2.21
- ✅ Navigation 3 (1.1.0-alpha05)
- ✅ Jetpack Compose
- ✅ Koin (Dependency Injection)
- ✅ kotlinx.serialization
- ✅ Kotlin Coroutines & Flow
- ✅ MVI Pattern
- ✅ Clean Architecture
✅ Lista zamówień z mock danymi
✅ Szczegóły zamówienia
✅ Nawigacja typu type-safe
✅ Zarządzanie stanem (MVI)
✅ Dependency Injection (Koin)
✅ Modularyzacja
✅ Abstrakcja nawigacji
./gradlew assembleDebug
# lub
./gradlew installDebugZe względu na to, że Navigation 3 (1.1.0-alpha05) nie ma pełnej dokumentacji API dla NavDisplay, użyłem prostszego podejścia:
- Manual rendering na podstawie
backStack.lastOrNull() - Zamiast
NavDisplayzentryProvider(które nie jest dostępne w tej wersji)
- ✅
NavBackStackjestMutableList<NavKey> - ✅ Obserwujemy zmiany przez recomposition
- ✅ Wszystkie ViewModels działają poprawnie z Koin
- ✅ Nawigacja działa przez
backStack.add()ibackStack.removeLast()
Gdy Navigation 3 będzie miał stabilną wersję z pełnym API, można dodać:
- Animacje przejść
NavDisplayzentryProviderNavEntrydecorators dla lifecycle- Shared element transitions
Projekt kompiluje się bez błędów i jest gotowy do uruchomienia na emulatorze/urządzeniu.