-
Notifications
You must be signed in to change notification settings - Fork 658
Description
Description
I have a layout where a FAB triggers the bottom sheet, and then disappears so as not to cover it. When the sheet is dismissed, the button reappears (see the video under 'expected behaviour').
This works most of the time, however if the sheet is dismissed at a particular moment shortly after it's started, it seems that the the currentBackStackEntryAsState state isn't updated back to the prior destination, and therefore the action to show the button isn't run. There appears to be a race condition.
Video of the failing case:
broken.mp4
Steps to reproduce
- Press the button to switch to the sheet and hide the button.
- Press the scrim, just about at the time when the sheet animation stops.
- Observe that sheet is dismissed, but the button has not reappeared.
Also, in terms of a bit of troubleshooting...
- If I add a
printlnas follows:within myval navBackStackEntry by navController.currentBackStackEntryAsState() // existing line println("Route: ${navBackStackEntry?.destination?.route}") // new println
MainLayout, then in the erroneous case it ends onSHEET. TheHOMEnavigation does not appear to be triggered.
Full code below.
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.google.accompanist.navigation.material.*
class TestActivity2 : ComponentActivity() {
@OptIn(ExperimentalMaterialNavigationApi::class, ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val bottomSheetNavigator = rememberBottomSheetNavigator()
val navController = rememberNavController(bottomSheetNavigator)
var fabVisible by remember { mutableStateOf(true) }
Scaffold(
floatingActionButton = {
if (fabVisible) {
FloatingActionButton(onClick = {
navController.navigate(Destinations.SHEET.name)
}) {
Icon(
painter = rememberVectorPainter(image = Icons.Default.Star),
contentDescription = null
)
}
}
},
) {
MainLayout(
bottomSheetNavigator = bottomSheetNavigator,
navController = navController,
onShowSheet = { fabVisible = false },
onHideSheet = { fabVisible = true },
)
}
}
}
@OptIn(ExperimentalMaterialNavigationApi::class)
@Composable
fun MainLayout(
bottomSheetNavigator: BottomSheetNavigator,
navController: NavHostController,
onShowSheet: () -> Unit = {},
onHideSheet: () -> Unit = {}
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
if (navBackStackEntry?.destination?.route == Destinations.SHEET.name) {
onShowSheet()
} else {
onHideSheet()
}
ModalBottomSheetLayout(bottomSheetNavigator) {
NavHost(navController, Destinations.HOME.name) {
composable(route = Destinations.HOME.name) {
Text("This is the home.", fontSize = 16.sp)
}
bottomSheet(route = Destinations.SHEET.name) {
Text("This is the bottom sheet.", fontSize = 16.sp)
}
}
}
}
private enum class Destinations {
HOME, SHEET
}
}Expected behavior
The logic to re-enable the button is triggered, regardless of how quickly I dismiss the sheet.
ok.mp4
Additional context
Compose version 1.2.0-alpha03
Accompanist version 0.24.2-alpha
Android S (Pixel 3a) and Android S (Nexus 5 emulator)