我正在尝试覆盖后退按钮,以便在按下时(当我在某些 ModalNavigationDrawer 屏幕上时)它会显示底部导航并更改 IconButton。
当通过单击图标发生时,一切都会正常工作,但是当通过系统单击发生时,首先会出现一种到屏幕的转换,然后仅显示底部导航并更改 IconButton。
代码:
package com.example.bussiness.navigation
import android.annotation.SuppressLint
import android.content.ContentValues.TAG
import android.nfc.Tag
import android.util.Log
import androidx.activity.OnBackPressedCallback
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.compose.BackHandler
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Menu
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.NavigationDrawerItemDefaults
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.example.bussiness.screens.bottom_screens.ExpansesScreen
import com.example.bussiness.screens.bottom_screens.HomeScreen
import com.example.bussiness.screens.Screens
import com.example.bussiness.screens.bottom_screens.SellingScreen
import com.example.bussiness.screens.bottom_screens.StatisticsScreen
import com.example.bussiness.screens.drawer_screens.AboutScreen
import com.example.bussiness.screens.drawer_screens.ExpansesTemplatesScreen
import com.example.bussiness.screens.drawer_screens.FAQScreen
import com.example.bussiness.screens.drawer_screens.ProductScreen
import com.example.bussiness.screens.drawer_screens.SettingsScreen
import com.example.bussiness.screens.drawer_screens.SupportScreen
import kotlinx.coroutines.android.awaitFrame
import kotlinx.coroutines.launch
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NavigationSheet() {
val navigationController = rememberNavController()
val coroutineScope = rememberCoroutineScope()
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
var selectedItemIndex by rememberSaveable { mutableStateOf(0) }
var selectedItemIndexDrawer by rememberSaveable { mutableStateOf(-1) }
var bottomNavigationVisibility by remember {
mutableStateOf(true)
}
var popUpped by remember {
mutableStateOf(false)
}
fun popBack() {
Log.d("---------------------", "Pop backed")
selectedItemIndexDrawer = -1
bottomNavigationVisibility = true
navigationController.navigateUp()
}
BackHandler(popUpped) {
popUpped = false
coroutineScope.launch { popBack() }
}
ModalNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = true,
drawerContent = {
ModalDrawerSheet {
Spacer(modifier = Modifier.height(16.dp))
drawer_items.forEachIndexed { index, item ->
NavigationDrawerItem(
label = {
Text(text = item.title)
},
selected = index == selectedItemIndexDrawer,
onClick = {
navigationController.navigate(item.screen) {
popUpTo(bottom_items[selectedItemIndex].screen) {
inclusive = false
saveState = false
}
}
selectedItemIndexDrawer = index
coroutineScope.launch {
drawerState.close()
}
bottomNavigationVisibility = false
popUpped = true
},
icon = {
Icon(
imageVector = if (index == selectedItemIndexDrawer) {
item.selectedIcon
} else item.unselectedIcon,
contentDescription = item.title
)
},
modifier = Modifier
.padding(NavigationDrawerItemDefaults.ItemPadding)
)
}
}
},
) {
Scaffold (
topBar = {
val scope = rememberCoroutineScope()
TopAppBar(title = { Text(text = "Main screen") },
colors = TopAppBarDefaults.topAppBarColors(),
navigationIcon = {
if (selectedItemIndexDrawer == -1) {
IconButton(
onClick = { scope.launch { drawerState.open() } }
) {
Icon(imageVector = Icons.Outlined.Menu, contentDescription = "Menu")
}
}
else {
IconButton(
onClick = { scope.launch { popBack() } }
) {
Icon(imageVector = Icons.Outlined.ArrowBack, contentDescription = "Back")
}
}
}
)
},
bottomBar = {
if (bottomNavigationVisibility) {
NavigationBar {
bottom_items.forEachIndexed { index, item ->
NavigationBarItem(
selected = selectedItemIndex == index,
onClick = {
selectedItemIndex = index
navigationController.navigate(item.screen) {
popUpTo(Screens.Home.route) {
inclusive = false
saveState = true
}
}
},
label = {
Text(text = item.title)
},
alwaysShowLabel = false,
icon = {
Icon(
imageVector = if (index == selectedItemIndex) {
item.selectedIcon
} else item.unselectedIcon,
contentDescription = item.title
)
}
)
}
}
}
}
) { padding ->
NavHost(navController = navigationController, startDestination = Screens.Home.route) {
composable(Screens.Home.route) { HomeScreen(navController = navigationController, padding) }
composable(Screens.Selling.route) { SellingScreen(navController = navigationController, padding) }
composable(Screens.Expanses.route) { ExpansesScreen(navController = navigationController, padding) }
composable(Screens.Statistics.route) { StatisticsScreen(navController = navigationController, padding) }
composable(Screens.Products.route) { ProductScreen(navController = navigationController, padding) }
composable(Screens.Expanses_Templates.route) { ExpansesTemplatesScreen(navController = navigationController, padding) }
composable(Screens.Settings.route) { SettingsScreen(navController = navigationController, padding) }
composable(Screens.FAQ.route) { FAQScreen(navController = navigationController, padding) }
composable(Screens.About.route) { AboutScreen(navController = navigationController, padding) }
composable(Screens.Support.route) { SupportScreen(navController = navigationController, padding) }
}
}
}
}
我试过了
OnBackPressedDispatcherOwner
,效果是一样的。
我将非常高兴获得任何帮助,即使是与此问题没有直接关系的帮助,提前致谢
阅读此评论:问题
因此,您应该将 BackHandler 放在 NavHost 下方,如下所示:
{ padding ->
NavHost(navController = navigationController, startDestination = Screens.Home.route) {
composable(Screens.Home.route) { HomeScreen(navController = navigationController, padding) }
composable(Screens.Selling.route) { SellingScreen(navController = navigationController, padding) }
composable(Screens.Expanses.route) { ExpansesScreen(navController = navigationController, padding) }
composable(Screens.Statistics.route) { StatisticsScreen(navController = navigationController, padding) }
composable(Screens.Products.route) { ProductScreen(navController = navigationController, padding) }
composable(Screens.Expanses_Templates.route) { ExpansesTemplatesScreen(navController = navigationController, padding) }
composable(Screens.Settings.route) { SettingsScreen(navController = navigationController, padding) }
composable(Screens.FAQ.route) { FAQScreen(navController = navigationController, padding) }
composable(Screens.About.route) { AboutScreen(navController = navigationController, padding) }
composable(Screens.Support.route) { SupportScreen(navController = navigationController, padding) }
}
BackHandler(popUpped) {
popUpped = false
coroutineScope.launch { popBack() }
}
}
希望这对您有帮助