从 jetpack 组合导航使用 popBackStack 时如何更改脚手架顶部栏的标题?

How to change title for scaffold top bar when using popBackStack from jetpack compose navigation?

我正在将我的多个 activity 应用程序迁移到单个 activity 应用程序以进行撰写。

我创建了一个可组合的主页,其中包含一个标题如下所示的顶部应用栏:


@Composable
fun Home() {
val navController = rememberNavController()
    var actionBarTitle by rememberSaveable { mutableStateOf("Home") }
    var actionBarSubtitle by rememberSaveable { mutableStateOf("") }
    Scaffold(topBar = {
        Header(title = actionBarTitle, subTitle = actionBarSubtitle,
                onBackPress = { navController.popBackStack() },
            showInfo = true, onActionClick = {
                navController.navigate(Screen.Info.route)
            }, modifier = Modifier.fillMaxWidth())
    }) {
        AppNavigation(navController = navController, onNavigate = { title, subtitle ->
                actionBarTitle = title
                actionBarSubtitle = subtitle
            })
}


每当我对任何屏幕使用 navController.navigate 时都会触发 onNavigate,如下所示:


onNavigate("Top up", "Please topm up with minimum of X amount")
navController.navigateTo(Screen.TopUp.route)

我的问题是,当我使用 backpress 时,我不知道我将被导航到哪个屏幕可组合项,所以我如何调用 onNavigate 来更改标题。

您可以使用currentBackstackEntryFlow观察导航变化。

@Composable
fun Home() {
    val context = LocalContext.current
    val navController = rememberNavController()
    ...
    LaunchedEffect(navController) {
        navController.currentBackStackEntryFlow.collect { backStackEntry ->
            // You can map the title based on the route using:
            actionBarTitle = getTitleByRoute(context, backStackEntry.destination.route)
        }
    }
    ...
}

当然,你需要写这个getTitleByRoute()才能根据导航路线得到正确的标题。 它会是这样的:

fun getTitleByRoute(context: Context, route:String): String {
    return when (route) {
        "Screen1" -> context.getString(R.string.title_screen_1)
        // other cases
        else -> context.getString(R.string.title_home)
    }
}

1.使用 Composable

时使用 LiveData 更改屏幕标题

实施“androidx.compose.runtime:runtime-livedata:1.2.0-beta02”

2。创建视图模型 Class

class MainViewModel: ViewModel() {
    private var _screenTitle = MutableLiveData("")
    val screenTitle: LiveData<String>
        get() = _screenTitle

    fun setTitle(newTitle: String) {
        _screenTitle.value = newTitle
    }
}

3。在你的 Activity Class

setContent {
        Surface(color = MaterialTheme.colors.onPrimary) {
            LoadMainScreen()
        }
    } 

//观察屏幕标题

@Composable
fun LoadMainScreen(mainViewModel: MainViewModel = viewModel()){

val title: String by mainViewModel.screenTitle.observeAsState("")

 Scaffold(
    topBar = {
        TopAppBar(title = { title?.let { Text(it) } },

          navigationIcon = {
          Icon(
                imageVector = Icons.Default.Menu,
                contentDescription = "Menu",
                tint = Color.White
              )
          }           
        )
      } 
    )
}  

4.从屏幕更改标题值

@Composable
fun ScreenOne(mainViewModel: MainViewModel) {
    LaunchedEffect(Unit){
        mainViewModel.setTitle("One")
    }
}
@Composable
fun ScreenTwo(mainViewModel: MainViewModel) {
    LaunchedEffect(Unit){
        mainViewModel.setTitle("Two")
    }
}