Anonymous
BackHandler не работает с первого раза JetPack Compose
Сообщение
Anonymous » 05 май 2024, 21:15
Я пытаюсь переопределить кнопку «Назад», чтобы при нажатии (когда я нахожусь на каком-либо экране 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, эффект тот же.
Я был бы очень рад любой помощи, даже той, которая дает не имеет прямого отношения к этой проблеме, заранее спасибо
Подробнее здесь:
https://stackoverflow.com/questions/784 ... ck-compose
1714932918
Anonymous
Я пытаюсь переопределить кнопку «Назад», чтобы при нажатии (когда я нахожусь на каком-либо экране ModalNavigationDrawer) она отображала нижнюю навигацию, а также меняла кнопку IconButton. Когда это произойдет по клику на иконку все работает как надо, но когда это происходит по системному клику, то сначала происходит своеобразный переход на экран, а потом показывается только нижняя навигация и тоже меняется IconButton.Видео экрана Код: [code]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) } } } } } [/code] Я попробовал OnBackPressedDispatcherOwner, эффект тот же. Я был бы очень рад любой помощи, даже той, которая дает не имеет прямого отношения к этой проблеме, заранее спасибо Подробнее здесь: [url]https://stackoverflow.com/questions/78433240/backhandler-does-not-work-the-first-time-jetpack-compose[/url]