Android Compose setupWithNavController

问题描述 投票:0回答:1

我正在寻找 setupWithNavController(Toolbar, NavController) 的 Compose 变体,以便在导航目的地发生变化时自动更新

AppBar
中的向上按钮。 到目前为止我还没有发现任何有用的东西。

Compose 中这被认为是糟糕的设计吗?或者是否有一些简单的方法可以实现我没有看到的相同效果?

android android-navigation android-jetpack-compose
1个回答
5
投票

我已经想出了一个解决方案,但我不满意。


androidx.navigation:navigation-compose:1.0.0-alpha08
提供了一个扩展函数来观察current返回堆栈条目。

@Composable
fun NavController.currentBackStackEntryAsState(): State<NavBackStackEntry?>

我创建了一个类似的扩展来观察前一个返回堆栈条目

/**
 * Gets the previous navigation back stack entry as a [MutableState]. When the given navController
 * changes the back stack due to a [NavController.navigate] or [NavController.popBackStack] this
 * will trigger a recompose and return the second top entry on the back stack.
 *
 * @return a mutable state of the previous back stack entry
 */
@Composable
fun NavController.previousBackStackEntryAsState(): State<NavBackStackEntry?> {
    val previousNavBackStackEntry = remember { mutableStateOf(previousBackStackEntry) }
    // setup the onDestinationChangedListener responsible for detecting when the
    // previous back stack entry changes
    DisposableEffect(this) {
        val callback = NavController.OnDestinationChangedListener { controller, _, _ ->
            previousNavBackStackEntry.value = controller.previousBackStackEntry
        }
        addOnDestinationChangedListener(callback)
        // remove the navController on dispose (i.e. when the composable is destroyed)
        onDispose {
            removeOnDestinationChangedListener(callback)
        }
    }
    return previousNavBackStackEntry
}

以及后退按钮的可组合项

@Composable
fun NavigationIcon(navController: NavController): @Composable (() -> Unit)? {
    val previousBackStackEntry: NavBackStackEntry? by navController.previousBackStackEntryAsState()
    return previousBackStackEntry?.let {
        {
            IconButton(onClick = {
                navController.popBackStack()
            }) {
                Icon(Icons.Default.ArrowBack, contentDescription = "Up button")
            }
        }
    }
}

我必须返回

@Composable (() -> Unit)?
(而不是可组合函数常见的无返回值),因为
TopAppBar
使用可空性来检查是否将标题偏移 16dp(不带图标)或 72dp(带图标)。

最后,内容是这样的

@Composable
fun MainContent() {
    val navController: NavHostController = rememberNavController()

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Weather") },
                navigationIcon = { NavigationIcon(navController) }
            )
        },
    ) {
        NavHost(
            navController,
            startDestination = "list"
        ) {
            composable("list") {
                ...
            }
            composable("detail") {
                ...
            }
        }
    }
}

列表:

详情:

创建自定义

NavigationTopAppBar
可组合项并将
NavController
NavigationIcon
中提升出来可能会更清晰,但想法保持不变。我没有费心进一步修补。


我还尝试根据 current NavGraph 目的地自动更新标题。不幸的是,没有一种可靠的方法可以在不从

androidx.navigation:navigation-compose
库中提取大量内部实现的情况下为目的地设置标签。

© www.soinside.com 2019 - 2024. All rights reserved.