Существует ли правильный пример навигации, защищенной от типов с вложенными графиками, где один из графов включает в себя навигационный балл с собственными экранами, а экран Auth/Splash/Onbarting удаляется из заднего стека, используя Inclusive = True, все без дублирования MamplicatingNavController/NAVHOST?@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
IncomeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
NavigationHost()
}
}
}
}
}
@Serializable
sealed class Graph {
@Serializable
object OnboardingGraph : Graph()
@Serializable
object MainGraph : Graph()
}
@Serializable
sealed class OnboardingGraph {
@Serializable
object OnboardingScreen : OnboardingGraph()
}
@Serializable
sealed class MainGraph {
@Serializable
object Home : MainGraph()
@Serializable
object Notification : MainGraph()
@Serializable
object History : MainGraph()
@Serializable
object Settings : MainGraph()
}
enum class TopLevelRoute(
val route: Any,
@StringRes val label: Int,
@DrawableRes val iconFill: Int
) {
HOME(
MainGraph.Home,
R.string.tab_home,
R.drawable.baseline_home_24
),
NOTIFICATION(
MainGraph.Notification,
R.string.tab_notification,
R.drawable.baseline_notifications_24
),
HISTORY(
MainGraph.History,
R.string.tab_history,
R.drawable.baseline_history_edu_24
),
SETTINGS(
MainGraph.Settings,
R.string.tab_settings,
R.drawable.baseline_settings_24
);
}
@Composable
fun BottomNavigationBar(
navController: NavHostController,
currentDestination: NavDestination?
) {
NavigationBar {
TopLevelRoute.entries.forEach { navigationItem ->
NavigationBarItem(
selected = currentDestination?.hierarchy?.any {
it.hasRoute(navigationItem.route::class)
} == true,
label = {
Text(text = stringResource(navigationItem.label))
},
icon = {
Icon(
painterResource(navigationItem.iconFill),
contentDescription = stringResource(navigationItem.label)
)
},
onClick = {
navController.navigate(navigationItem.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
@Composable
private fun NavigationHost() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Graph.OnboardingGraph,
enterTransition = { EnterTransition.None },
exitTransition = { ExitTransition.None }
) {
onboardingNavGraph(navController)
composable {
MainScreenUI(navController = navController)
}
}
}
fun NavGraphBuilder.onboardingNavGraph(
navController: NavController
) {
navigation(startDestination = OnboardingGraph.OnboardingScreen) {
composable {
OnboardingScreen(
onFinished = {
navController.navigate(MainGraph.Home) {
popUpTo(OnboardingGraph.OnboardingScreen) {
inclusive = true
}
}
}
)
}
}
}
@Composable
fun MainScreenUI(
navController: NavHostController
) {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
BottomNavigationBar(
navController = navController,
currentDestination = currentDestination
)
}
) { paddingValues ->
NavHost(
modifier = Modifier.padding(paddingValues),
navController = navController,
startDestination = Graph.MainGraph,
enterTransition = { EnterTransition.None },
exitTransition = { ExitTransition.None }
) {
mainNavGraph(navController)
}
}
}
fun NavGraphBuilder.mainNavGraph(
navController: NavController
) {
navigation(startDestination = MainGraph.Home) {
composable {
HomeScreen { /* TODO */ }
}
composable {
NotificationScreen { /* TODO */ }
}
composable {
HistoryScreen { /* TODO */ }
}
composable {
SettingsScreen { /* TODO */ }
}
}
}
< /code>
также попробовал использование одного навигации с двумя вложенными графиками, но вызов: < /p>
navController.navigate(MainGraph.Home) {
popUpTo(OnboardingGraph.OnboardingScreen) {
inclusive = true
}
}
< /code>
Приводит к ошибке:
«Игнорирование Popbackstack в пункт назначения xxxxxx, так как он не был найден в текущем заднем стеке» < /strong>,
, а также мерцание экранов при снова навигации на тот же экран. Ошибка возникает из -за того, что при нажатии на нижний элемент навигации метод всплывающего количества вызывается с помощью начального идентификатора назначения, который определяется с использованием NavController.graph.findStartDestination (). ID. Тем не менее, начальное место назначения графика остается экраном адаптации, который уже был удален из заднего стека после его завершения. В результате предпринимается попытка «всплыть» на экран, который больше не существует в стеке. (В случае попытки использовать два строителя графика с одним навигацией) в настоящее время я вижу решение, установив экран maingraph \ home в качестве пункта назначения в нижней навигации вместо использования FindStartDestination () . Однако я не уверен, является ли это лучшей практикой. < /P>
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
IncomeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainScreenUI()
}
}
}
}
}
@Serializable
sealed class Graph {
@Serializable
object OnboardingGraph : Graph()
@Serializable
object MainGraph : Graph()
}
@Serializable
sealed class OnboardingGraph {
@Serializable
object OnboardingScreen : OnboardingGraph()
}
@Serializable
sealed class MainGraph {
@Serializable
object Home : MainGraph()
@Serializable
object Notification : MainGraph()
@Serializable
object History : MainGraph()
@Serializable
object Settings : MainGraph()
}
enum class TopLevelRoute(
val route: Any,
@StringRes val label: Int,
@DrawableRes val iconFill: Int
) {
HOME(
MainGraph.Home,
R.string.tab_home,
R.drawable.baseline_home_24
),
NOTIFICATION(
MainGraph.Notification,
R.string.tab_notification,
R.drawable.baseline_notifications_24
),
HISTORY(
MainGraph.History,
R.string.tab_history,
R.drawable.baseline_history_edu_24
),
SETTINGS(
MainGraph.Settings,
R.string.tab_settings,
R.drawable.baseline_settings_24
);
}
@Composable
fun MainScreenUI() {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
// distance check to exclude non-incoming screens
BottomNavigationBar(
navController = navController,
currentDestination = currentDestination
)
}
) { paddingValues ->
NavHost(
modifier = Modifier.padding(paddingValues),
navController = navController,
startDestination = Graph.OnboardingGraph,
enterTransition = { EnterTransition.None },
exitTransition = { ExitTransition.None }
) {
onboardingNavGraph(navController)
mainNavGraph(navController)
}
}
}
@Composable
fun BottomNavigationBar(
navController: NavHostController,
currentDestination: NavDestination?
) {
NavigationBar {
TopLevelRoute.entries.forEach { navigationItem ->
NavigationBarItem(
selected = currentDestination?.hierarchy?.any {
it.hasRoute(navigationItem.route::class)
} == true,
label = {
Text(text = stringResource(navigationItem.label))
},
icon = {
Icon(
painterResource(navigationItem.iconFill),
contentDescription = stringResource(navigationItem.label)
)
},
onClick = {
navController.navigate(navigationItem.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
fun NavGraphBuilder.onboardingNavGraph(
navController: NavController
) {
navigation(startDestination = OnboardingGraph.OnboardingScreen) {
composable {
OnboardingScreen(
onFinished = {
navController.navigate(MainGraph.Home) {
popUpTo(OnboardingGraph.OnboardingScreen) {
inclusive = true
}
}
}
)
}
}
}
fun NavGraphBuilder.mainNavGraph(
navController: NavController
) {
navigation(startDestination = MainGraph.Home) {
composable {
HomeScreen { /* TODO */ }
}
composable {
NotificationScreen { /* TODO */ }
}
composable {
HistoryScreen { /* TODO */ }
}
composable {
SettingsScreen { /* TODO */ }
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/795 ... popup-in-j
Навигация по типам с вложенными графиками, навигацией и инклюзивным всплыванием в JetPack Compose ⇐ Android
Форум для тех, кто программирует под Android
1741802507
Anonymous
Существует ли правильный пример навигации, защищенной от типов с вложенными графиками, где один из графов включает в себя навигационный балл с собственными экранами, а экран Auth/Splash/Onbarting удаляется из заднего стека, используя Inclusive = True, все без дублирования MamplicatingNavController/NAVHOST?@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
IncomeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
NavigationHost()
}
}
}
}
}
@Serializable
sealed class Graph {
@Serializable
object OnboardingGraph : Graph()
@Serializable
object MainGraph : Graph()
}
@Serializable
sealed class OnboardingGraph {
@Serializable
object OnboardingScreen : OnboardingGraph()
}
@Serializable
sealed class MainGraph {
@Serializable
object Home : MainGraph()
@Serializable
object Notification : MainGraph()
@Serializable
object History : MainGraph()
@Serializable
object Settings : MainGraph()
}
enum class TopLevelRoute(
val route: Any,
@StringRes val label: Int,
@DrawableRes val iconFill: Int
) {
HOME(
MainGraph.Home,
R.string.tab_home,
R.drawable.baseline_home_24
),
NOTIFICATION(
MainGraph.Notification,
R.string.tab_notification,
R.drawable.baseline_notifications_24
),
HISTORY(
MainGraph.History,
R.string.tab_history,
R.drawable.baseline_history_edu_24
),
SETTINGS(
MainGraph.Settings,
R.string.tab_settings,
R.drawable.baseline_settings_24
);
}
@Composable
fun BottomNavigationBar(
navController: NavHostController,
currentDestination: NavDestination?
) {
NavigationBar {
TopLevelRoute.entries.forEach { navigationItem ->
NavigationBarItem(
selected = currentDestination?.hierarchy?.any {
it.hasRoute(navigationItem.route::class)
} == true,
label = {
Text(text = stringResource(navigationItem.label))
},
icon = {
Icon(
painterResource(navigationItem.iconFill),
contentDescription = stringResource(navigationItem.label)
)
},
onClick = {
navController.navigate(navigationItem.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
@Composable
private fun NavigationHost() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Graph.OnboardingGraph,
enterTransition = { EnterTransition.None },
exitTransition = { ExitTransition.None }
) {
onboardingNavGraph(navController)
composable {
MainScreenUI(navController = navController)
}
}
}
fun NavGraphBuilder.onboardingNavGraph(
navController: NavController
) {
navigation(startDestination = OnboardingGraph.OnboardingScreen) {
composable {
OnboardingScreen(
onFinished = {
navController.navigate(MainGraph.Home) {
popUpTo(OnboardingGraph.OnboardingScreen) {
inclusive = true
}
}
}
)
}
}
}
@Composable
fun MainScreenUI(
navController: NavHostController
) {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
BottomNavigationBar(
navController = navController,
currentDestination = currentDestination
)
}
) { paddingValues ->
NavHost(
modifier = Modifier.padding(paddingValues),
navController = navController,
startDestination = Graph.MainGraph,
enterTransition = { EnterTransition.None },
exitTransition = { ExitTransition.None }
) {
mainNavGraph(navController)
}
}
}
fun NavGraphBuilder.mainNavGraph(
navController: NavController
) {
navigation(startDestination = MainGraph.Home) {
composable {
HomeScreen { /* TODO */ }
}
composable {
NotificationScreen { /* TODO */ }
}
composable {
HistoryScreen { /* TODO */ }
}
composable {
SettingsScreen { /* TODO */ }
}
}
}
< /code>
также попробовал использование одного навигации с двумя вложенными графиками, но вызов: < /p>
navController.navigate(MainGraph.Home) {
popUpTo(OnboardingGraph.OnboardingScreen) {
inclusive = true
}
}
< /code>
Приводит к ошибке:
[b] «Игнорирование Popbackstack в пункт назначения xxxxxx, так как он не был найден в текущем заднем стеке» < /strong>,
, а также мерцание экранов при снова навигации на тот же экран. Ошибка возникает из -за того, что при нажатии на нижний элемент навигации метод всплывающего количества вызывается с помощью начального идентификатора назначения, который определяется с использованием NavController.graph.findStartDestination (). ID. Тем не менее, начальное место назначения графика остается экраном адаптации, который уже был удален из заднего стека после его завершения. В результате предпринимается попытка «всплыть» на экран, который больше не существует в стеке. (В случае попытки использовать два строителя графика с одним навигацией) в настоящее время я вижу решение, установив экран maingraph \ home [/b] в качестве пункта назначения в нижней навигации вместо использования FindStartDestination () . Однако я не уверен, является ли это лучшей практикой. < /P>
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
IncomeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainScreenUI()
}
}
}
}
}
@Serializable
sealed class Graph {
@Serializable
object OnboardingGraph : Graph()
@Serializable
object MainGraph : Graph()
}
@Serializable
sealed class OnboardingGraph {
@Serializable
object OnboardingScreen : OnboardingGraph()
}
@Serializable
sealed class MainGraph {
@Serializable
object Home : MainGraph()
@Serializable
object Notification : MainGraph()
@Serializable
object History : MainGraph()
@Serializable
object Settings : MainGraph()
}
enum class TopLevelRoute(
val route: Any,
@StringRes val label: Int,
@DrawableRes val iconFill: Int
) {
HOME(
MainGraph.Home,
R.string.tab_home,
R.drawable.baseline_home_24
),
NOTIFICATION(
MainGraph.Notification,
R.string.tab_notification,
R.drawable.baseline_notifications_24
),
HISTORY(
MainGraph.History,
R.string.tab_history,
R.drawable.baseline_history_edu_24
),
SETTINGS(
MainGraph.Settings,
R.string.tab_settings,
R.drawable.baseline_settings_24
);
}
@Composable
fun MainScreenUI() {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
// distance check to exclude non-incoming screens
BottomNavigationBar(
navController = navController,
currentDestination = currentDestination
)
}
) { paddingValues ->
NavHost(
modifier = Modifier.padding(paddingValues),
navController = navController,
startDestination = Graph.OnboardingGraph,
enterTransition = { EnterTransition.None },
exitTransition = { ExitTransition.None }
) {
onboardingNavGraph(navController)
mainNavGraph(navController)
}
}
}
@Composable
fun BottomNavigationBar(
navController: NavHostController,
currentDestination: NavDestination?
) {
NavigationBar {
TopLevelRoute.entries.forEach { navigationItem ->
NavigationBarItem(
selected = currentDestination?.hierarchy?.any {
it.hasRoute(navigationItem.route::class)
} == true,
label = {
Text(text = stringResource(navigationItem.label))
},
icon = {
Icon(
painterResource(navigationItem.iconFill),
contentDescription = stringResource(navigationItem.label)
)
},
onClick = {
navController.navigate(navigationItem.route) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
fun NavGraphBuilder.onboardingNavGraph(
navController: NavController
) {
navigation(startDestination = OnboardingGraph.OnboardingScreen) {
composable {
OnboardingScreen(
onFinished = {
navController.navigate(MainGraph.Home) {
popUpTo(OnboardingGraph.OnboardingScreen) {
inclusive = true
}
}
}
)
}
}
}
fun NavGraphBuilder.mainNavGraph(
navController: NavController
) {
navigation(startDestination = MainGraph.Home) {
composable {
HomeScreen { /* TODO */ }
}
composable {
NotificationScreen { /* TODO */ }
}
composable {
HistoryScreen { /* TODO */ }
}
composable {
SettingsScreen { /* TODO */ }
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79504499/type-safe-navigation-with-nested-graphs-navigationbar-and-inclusive-popup-in-j[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия