Kotlin-Android-Open-Source/solivagant

 
 

Repository files navigation

  • Integrate with Jetpack Compose and Compose Multiplatform seamlessly.

  • Integrate with kmp-viewmodel library seamlessly

    • Stack entry scoped ViewModel, exists as long as the stack entry is on the navigation stack, including the configuration changes on Android.
    • Supports SavedStateHandle, used to save and restore data over configuration changes or process death on Android.
  • Type safety navigation, easy to pass data between destinations.

  • Supports Multi-Backstacks, this is most commonly used in apps that use bottom navigation to separate the back stack of each tab. See Freeletics Navigation - Multiple back stacks.

  • Supports Lifecycle events, similar to AndroidX Lifecycle library.

maven-centralcodecovGitHub licenseKotlin versionKotlinX Coroutines versionCompose Multiplatform versionHits

badgebadgebadgebadgebadgebadgebadgebadgebadgebadgebadgebadge

Liked some of my work? Buy me a coffee (or more likely a beer)

Buy Me A Coffee

allprojects {
  repositories {
    [...]
    mavenCentral()
  }
}
implementation("io..hoc081098:solivagant-navigation:0.0.1-alpha01")
  • The concept is similar to Freeletics Navigation library, so you can read the Freeletics Navigation to understand the concept.
@Immutable
@Parcelize
data object StartScreenRoute : NavRoute, NavRoot

@Immutable
@Parcelize
data object SearchProductScreenRoute : NavRoute
@JvmField
val StartScreenDestination: NavDestination =
  ScreenDestination<StartScreenRoute> { StartScreen() }

@Composable
internal fun StartScreen(
  modifier: Modifier = Modifier,
  viewModel: StartViewModel = koinKmpViewModel(),
) {
  // UI Composable
}

class StartViewModel(
  // used to trigger navigation actions from outside the view layer (e.g. from a ViewModel).
  // Usually, it is singleton object, or the host Activity retained scope.
  private val navigator: NavEventNavigator,
) : ViewModel() {
  internal fun navigateToProductsScreen() = navigator.navigateTo(ProductsScreenRoute)
  internal fun navigateToSearchProductScreen() = navigator.navigateTo(SearchProductScreenRoute)
}
@JvmField
val SearchProductScreenDestination: NavDestination =
  ScreenDestination<SearchProductScreenRoute> { SearchProductsScreen() }

@Composable
fun SearchProductsScreen(
  modifier: Modifier = Modifier,
  viewModel: SearchProductsViewModel = koinKmpViewModel<SearchProductsViewModel>(),
) {
  // UI Composable
}

class SearchProductsViewModel(
  private val searchProducts: SearchProducts,
  private val savedStateHandle: SavedStateHandle,
  // used to trigger navigation actions from outside the view layer (e.g. from a ViewModel).
  // Usually, it is singleton object, or the host Activity retained scope.
  private val navigator: NavEventNavigator,
) : ViewModel() {
  fun navigateToProductDetail(id: Int) {
    navigator.navigateTo(ProductDetailScreenRoute(id))
  }
}
@Stable
private val AllDestinations: ImmutableSet<NavDestination> = persistentSetOf(
  StartScreenDestination,
  SearchProductScreenDestination,
  // and more ...
)

@Composable
fun MyAwesomeApp(
  // used to trigger navigation actions from outside the view layer (e.g. from a ViewModel).
  // Usually, it is singleton object, or the host Activity retained scope.
  navigator: NavEventNavigator,
  modifier: Modifier = Modifier,
) {
  var currentRoute: BaseRoute? by remember { mutableStateOf(null) }

  NavHost(
    modifier = modifier,
    // route to the screen that should be shown initially
    startRoute = StartScreenRoute,
    // should contain all destinations that can be navigated to
    destinations = AllDestinations,
    navEventNavigator = navigator,
    destinationChangedCallback = { currentRoute = it },
  )
}
class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle) {
    super.onCreate()

    // navigator can be retrieved from the DI container, such as Koin, Dagger Hilt, etc.

    setContent {
      MyAwesomeApp(
        navigator = navigator
      )
    }
  }
}
// navigate to the destination that the given route leads to
navigator.navigateTo(DetailScreenRoute("some-id"))
// navigate up in the hierarchy
navigator.navigateUp()
// navigate to the previous destination in the backstack
navigator.navigateBack()
// navigate back to the destination belonging to the referenced route and remove all destinations
// in between from the back stack, depending on inclusive the destination
navigator.navigateBackTo<MainScreenRoute>(inclusive = false)
  • Samples sample: a complete sample using Compose Multiplatform (Android, Desktop, iOS)
    • solivagant-navigation for navigation in Compose Multiplatform.
    • kmp-viewmodel to share ViewModel and SavedStateHandle.
    • Koin DI.
  • Add more tests
  • Support transition when navigating
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

About

Compose Multiplatform Navigation - Pragmatic, type safety navigation for Compose Multiplatform. Based on Freeletics Navigation.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Kotlin 99.8%
  • Shell 0.2%