Белый экран и приложение зависают при двойном нажатии верхней кнопки навигации в приложении Android Jetpack Compose.Android

Форум для тех, кто программирует под Android
Anonymous
Белый экран и приложение зависают при двойном нажатии верхней кнопки навигации в приложении Android Jetpack Compose.

Сообщение Anonymous »

В моем приложении я использую TopAppBar со значком гамбургера и NavigationView (ModalNavigationDrawer + ModalDrawerSheet). Проблема заключается в том, что я дважды нажимаю значок навигации или когда я нажимаю значок навигации на экране настроек, а затем снова нажимаю на значок навигации дома. Странное поведение происходит, когда приложение показывает белый экран, например зависает, и у меня не было ошибок или исключений.
Вот GIF-файл, показывающий проблему
Изображение

Мой код:
HomeScreen
@Composable
fun HomeScreen(
stateHomeScreen: StateHomeScreen,
event: (EventHomeScreen) -> Unit,
navController: NavController,
onMenuClick: () -> Unit,
networkStatus: NetworkStatus,
snackbarHostState: SnackbarHostState

) {
val scope = rememberCoroutineScope()

Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.verticalScroll(state = rememberScrollState())
) {

HomeHeader(
onMenuClicked = { onMenuClick() },
onSettingsClicked = {
navController.navigate(Routes.SettingsScreen.route)
},
)

Spacer(modifier = Modifier.height(MediumSpacerHeight))
AppDropDownMenu(
menuName = "Number of Questions:",
menuList = Constants.numbersAsString,
text = stateHomeScreen.numberOfQuizzes.toString(),
onDropDownClick = {
event(EventHomeScreen.SetNumberOfQuizzes(it.toInt()))
})

// Spacer(modifier = Modifier.height(4.dp))
AppDropDownMenu(
menuName = "Select Category:",
menuList = Constants.categories,
text = stateHomeScreen.category,
onDropDownClick = {
event(EventHomeScreen.SetQuizCategory(it))
})

// Spacer(modifier = Modifier.height(SmallSpacerHeight))
AppDropDownMenu(
menuName = "Select of Difficulty:",
menuList = Constants.difficulty,
text = stateHomeScreen.difficulty,
onDropDownClick = {
event(EventHomeScreen.SetQuizDifficulty(it))

})

// Spacer(modifier = Modifier.height(SmallSpacerHeight))
AppDropDownMenu(
menuName = "Select Type:", menuList = Constants.type,
text = stateHomeScreen.type,
onDropDownClick = {
event(EventHomeScreen.SetQuizType(it))
})

AdBannerView()
Spacer(Modifier.height(Dimens.SmallPadding))

ButtonBox(
"Generate Quiz", padding = MediumPadding
) {
if (networkStatus == NetworkStatus.Unavailable) {

scope.launch {
snackbarHostState.showSnackbar(
message = "⚠️ No Internet Connection",
actionLabel = "Dismiss",
duration = SnackbarDuration.Long
)
}
return@ButtonBox
} else {
navController.navigate(
route = Routes.QuizScreen.passQuizParams(
stateHomeScreen.numberOfQuizzes,
stateHomeScreen.category,
difficulty = stateHomeScreen.difficulty,
type = stateHomeScreen.type
)
)
}
}
Spacer(modifier = Modifier.height(Dimens.LargePadding))

}

}

@Composable
fun ButtonBox(text: String, padding: Dp, onButtonClicked: () -> Unit) {
Button(
onClick = { onButtonClicked() },
modifier = Modifier
.fillMaxWidth()
.padding(padding)
) {
Text(
text, fontSize = Dimens.MediumTextSize,
style = MaterialTheme.typography.labelMedium.copy(fontWeight = FontWeight.SemiBold)
)
}
}


HomeHeader
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeHeader(
onMenuClicked: () -> Unit = {},
onSettingsClicked: () -> Unit = {}
) {
TopAppBar(
title = {
Text( modifier = Modifier.fillMaxWidth(),
text = "Quizzy",
fontSize = HeroTextSize,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.secondary,

textAlign = TextAlign.Center
)
},
navigationIcon = {
IconButton(
onClick = onMenuClicked,
modifier = Modifier
.size(40.dp)
.padding(start = 8.dp),
) {
Icon(
imageVector = Icons.Default.Menu,
contentDescription = "Menu",
tint = MaterialTheme.colorScheme.secondary,
)
}
},
actions = {

IconButton(onClick = onSettingsClicked) {
Icon(
contentDescription = "Settings",
tint = colorResource(R.color.colorSecondary),
imageVector = Icons.Default.Settings,

)
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = colorResource(R.color.colorPrimaryVariant)
),

modifier = Modifier.clip(
RoundedCornerShape(
bottomStart = Dimens.LargeCornerRadius,
bottomEnd = Dimens.LargeCornerRadius
)
)
)
}

ModalNavGraph
ModalNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = drawerGesturesEnabled,
drawerContent = {
ModalDrawerSheet(
windowInsets = WindowInsets(0, 0, 0, 0),
drawerContainerColor = MaterialTheme.colorScheme.surface,
) {
AppDrawer(
currentRoute = currentRoute ?: Routes.HomeScreen.route,
userName = userName, // ← من ViewModel لاحقاً
userEmail = userEmail,
drawerItems = drawerItems,
onItemClick = { item ->
item.route?.let {
navController.navigate(it) {
popUpTo(Routes.HomeScreen.route) { saveState = true }
launchSingleTop = true
restoreState = true
}
}
},
onLogoutClick = {
scope.launch { drawerState.close() }
authViewModel.logout()
onLogout()
},
onCloseDrawer = {
scope.launch { drawerState.close() }
},
onRemoveAdsClick = {
if (AdManager.areAdsDisabled()) {
Toast.makeText(
context,
"Ads disabled — ${AdManager.getRemainingMinutes()} minutes remaining",
Toast.LENGTH_SHORT
).show()
} else if (AdManager.isRewardedReady()) {
AdManager.showRewardedAd(
activity = context as Activity,
onSessionActivated = { remaining ->
Toast.makeText(
context,
"🎉 Ads disabled for $remaining minutes!",
Toast.LENGTH_LONG
).show()
// ✅ حدّث الـ subtitle
},
onNotReady = {
Toast.makeText(
context,
"Ad not ready, try again",
Toast.LENGTH_SHORT
).show()
AdManager.loadRewardedAd(context)
}
)
} else {
Toast.makeText(context, "Loading ad, try again", Toast.LENGTH_SHORT)
.show()
AdManager.loadRewardedAd(context)
}
}
)
}
}
) {
NavHost(
navController = navController,
startDestination = Routes.HomeScreen.route
) {
composable(route = Routes.HomeScreen.route) {

HomeScreen(
stateHomeScreen = state,
event = homeScreenViewModel::onEvent,
navController = navController,
onMenuClick = {
Log.d("DRAWER", "onClick — isDrawerOpening=$isDrawerOpening, currentValue=${drawerState.currentValue}, isAnimating=${drawerState.isAnimationRunning}")

if (!isDrawerOpening && !drawerState.isOpen && !drawerState.isAnimationRunning) {
isDrawerOpening = true
scope.launch {
try {
drawerState.open()
} catch (e: Exception) {
Log.e("DRAWER", "Error: ${e.message}", e)
} finally {
isDrawerOpening = false
}
}
} else {
Log.d("DRAWER", "IGNORED")
}
},
networkStatus = networkStatus,
snackbarHostState = snackbarHostState
)
}

Вернуться в «Android»