Skip to main content

Crate cranpose_navigation

Crate cranpose_navigation 

Source
Expand description

§cranpose-navigation

cranpose-navigation provides a typed back stack and a composable NavHost. Routes can carry screen arguments, and each stack entry owns a view-model store.

Depend directly on cranpose-navigation when a Cranpose app needs screen navigation. The feature set is empty. The app also needs its usual cranpose host and renderer features; the navigation crate brings UI, animation, and cranpose-coroflow APIs as dependencies.

§Define routes and screens

rememberNavController stores the stack in the current composition. NavHost maps each route to a screen, while a screen callback can push a typed route:

use cranpose_navigation::{NavHost, rememberNavController};
use cranpose_ui::composable;

#[derive(Clone, PartialEq)]
enum Screen {
    Home,
    Detail { id: u32 },
}

#[composable]
fn App() {
    let nav = rememberNavController(Screen::Home);
    NavHost(nav, move |screen| match screen {
        Screen::Home => HomeScreen(move || nav.navigate(Screen::Detail { id: 7 })),
        Screen::Detail { id } => DetailScreen(id),
    });
}

#[composable]
fn HomeScreen(_open_detail: impl Fn() + 'static) {}

#[composable]
fn DetailScreen(_id: u32) {}

NavHost crossfades between screens and connects platform back requests to stack pop. Use NavHostWith for a custom transition and NavController::navigate_with for pop-up and single-top options.

§Saved state

Each back-stack entry has its own SaveableScope, so rememberSaveable in a screen keeps the state of that visit. A covered screen gets its state back, and a popped screen forgets it. Two visits of one route keep apart.

rememberNavController keeps the back stack and the screens’ saved state in memory. rememberSaveableNavController saves both at each save boundary and restores them when the app starts again. Its Saver gives each route a saved form and may read the forms that older builds wrote:

use cranpose_navigation::{NavHost, rememberSaveableNavController};
use cranpose_services::Saver;
use cranpose_ui::composable;

#[derive(Clone, PartialEq)]
enum Screen {
    Home,
    Detail { id: u32 },
}

fn routes() -> Saver<Screen> {
    Saver::new(
        |screen: &Screen| match screen {
            Screen::Home => "home".to_owned(),
            Screen::Detail { id } => format!("detail {id}"),
        },
        |saved| match saved {
            "home" => Some(Screen::Home),
            _ => saved.strip_prefix("detail ")?.parse().ok().map(|id| Screen::Detail { id }),
        },
    )
}

#[composable]
fn App() {
    let nav = rememberSaveableNavController("nav", Screen::Home, routes());
    NavHost(nav, move |screen| match screen {
        Screen::Home => {}
        Screen::Detail { id: _ } => {}
    });
}

Restoring keeps the entries beneath the first route the saver cannot read. When it cannot read the bottom entry, or nothing was saved, the back stack starts at the start route.

§Browser history

On the web, BindBrowserHistory(controller, saver) keeps the browser’s history in step with the back stack, as Compose Multiplatform’s bindToNavigation does. Each navigation adds an entry whose URL fragment is #/ and the route’s saved form. The browser’s Back pops and its Forward navigates again, and a pop in the app goes back in the history. A page opened or reloaded at a route’s fragment shows that route over the start. Elsewhere the call does nothing, so an app can make it unconditionally.

§Android API map

Android APICranpose API
rememberNavController() and startDestinationrememberNavController, NavController
NavHost and typed destinationsNavHost with a route match
Enter and exit transitionsNavHostWith
navigate, popBackStack, navigateUpnavigate, pop_back_stack, navigate_up
popUpTo, inclusive pop, single topnavigate_with, NavOptions
Current back-stack entrycurrent_route, back_stack
View model scoped to a back-stack entrycranpose_coroflow::viewModel inside a screen
rememberSaveable in a destinationrememberSaveable inside a screen
Back stack restored after process deathrememberSaveableNavController with a route Saver
Compose Multiplatform window.bindToNavigationBindBrowserHistory
Predictive back in NavHostNavHost follows the gesture; cranpose_services::PredictiveBackHandler for custom screens

Structs§

NavController
The back stack of a NavHost — Android’s NavController.
NavOptions
How NavController::navigate_with changes the back stack — Android’s NavOptions.

Functions§

BindBrowserHistory
Keeps the browser’s history and address bar in step with controller’s back stack — Compose Multiplatform’s bindToNavigation.
NavHost
Shows the screen on top of controller’s back stack — Android’s NavHost.
NavHostWith
NavHost with its own transition between screens — Compose’s NavHost(enterTransition, exitTransition) for a fade.
rememberNavController
A NavController whose back stack starts at start — Android’s rememberNavController() plus NavHost(startDestination).
rememberSaveableNavController
A NavController whose back stack is saved under key at each save boundary, as rememberSaveable state is, and restored when it is next created, after a process restart too. saver gives each route its saved form; it may read the forms older builds wrote.