从 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")
}
}
我正在将我的多个 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")
}
}