Navigation

RallyDestination でicon、route(destinationを指定するためのString)、表示するComposableをまとめてinterfaceとして定義(本来はComposableは分離するべきとのこと)
Overview, Accounts, Bills で各画面に対する値を指定

/**
 * Contract for information needed on every Rally navigation destination
 */
interface RallyDestination {
    val icon: ImageVector
    val route: String
    val screen: @Composable () -> Unit
}

/**
 * Rally app navigation destinations
 */
object Overview : RallyDestination {
    override val icon = Icons.Filled.PieChart
    override val route = "overview"
    override val screen: @Composable () -> Unit = { OverviewScreen() }
}

object Accounts : RallyDestination {
    override val icon = Icons.Filled.AttachMoney
    override val route = "accounts"
    override val screen: @Composable () -> Unit = { AccountsScreen() }
}

object Bills : RallyDestination {
    override val icon = Icons.Filled.MoneyOff
    override val route = "bills"
    override val screen: @Composable () -> Unit = { BillsScreen() }
}

実際に使う部分は以下

@Composable
fun RallyApp() {
    RallyTheme {
        var currentScreen: RallyDestination by remember { mutableStateOf(Overview) }
        Scaffold(
            topBar = {
                RallyTabRow(
                    allScreens = rallyTabRowScreens,
                    onTabSelected = { screen -> currentScreen = screen },
                    currentScreen = currentScreen
                )
            }
        ) { innerPadding ->
            Box(Modifier.padding(innerPadding)) {
                currentScreen.screen()
            }
        }
    }
}

val rallyTabRowScreens = listOf(Overview, Accounts, Bills)

currentScreenに初期状態としてOverviewを設定

NavController を取得するには、rememberNavController() 関数を呼び出します。これにより、(rememberSaveable を使用して)構成変更後も存続する NavController が作成されて記憶されます。
NavController は常に、コンポーザブル階層の最上位(通常は App コンポーザブル内)に作成して配置します。これにより、NavController を参照する必要があるすべてのコンポーザブルにアクセス権が付与されます。
特定のデスティネーションのコピーがバックスタックの一番上に最大で 1 つだけ配置されるように、Compose Navigation API には launchSingleTop フラグが用意されています。このフラグを次のように navController.navigate() アクションに渡すことができます。

とのことなのでComposableの一番上で
val navController = rememberNavController()
を呼んで使うようにする。
launchSingleTop に関しては全部のnavigate(route)に指定するのは非効率なので拡張関数を定義して使うのが良い

fun NavHostController.navigateSingleTopTo(route: String) =
    this.navigate(route) { launchSingleTop = true }

これを定義して以下のように使う。

navController.navigateSingleTopTo(newScreen.route)

また、navControllerはナビゲーション階層の最上位に配置し、下位に渡さないようにする。(独立しなくなる)
以下のように実行するメソッドを渡すようにする。

                composable(route = Overview.route) {
                    OverviewScreen(
                        onClickSeeAllAccounts = {
                            navController.navigateSingleTopTo(Accounts.route)
                        },
                        onClickSeeAllBills = {
                            navController.navigateSingleTopTo(Bills.route)
                        }
                    )
                }


参考:Jetpack Compose Navigation  |  Android Developers