androidkotlinandroid-jetpack-composematerial-components-android

Why pull-to-refresh box disappears after navigating back to screen then swiping up/down or click?


I'm working on a Jetpack Compose application that implements a Material3 new pull-to-refresh (PullToRefreshBox) feature. However, I've encountered an issue where the pull-to-refresh box disappears after I navigate back to the screen or when I swipe up/down the screen.

Issues I'm facing: Disappearance of pull-to-refresh Indicator: When I navigate away from this screen and then come back, scrolling screen or clicking screen the pull-to-refresh indicator disappears instantly while refreshing task is going on.

Behavior on swipe up/down: Additionally, when I swipe up or down, the pull-to-refresh indicator disappears unexpectedly.

enter image description here

@AndroidEntryPoint
class TestActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApp()
        }
    }
}

@Composable
fun MyApp() {
    // Define the routes and their respective icons
    val topLevelRoutes = listOf(
        TopLevelRoute("Profile", "profile", Icons.Filled.AccountCircle),
        TopLevelRoute("Friends", "friends", Icons.Filled.People)
    )

    // Create a NavController
    val navController = rememberNavController()

    Scaffold(
        bottomBar = {
            BottomNavigation {
                val navBackStackEntry by navController.currentBackStackEntryAsState()
                val currentDestination = navBackStackEntry?.destination
                topLevelRoutes.forEach { topLevelRoute ->
                    BottomNavigationItem(
                        icon = {
                            Icon(
                                topLevelRoute.icon,
                                contentDescription = topLevelRoute.name
                            )
                        },
                        label = { Text(topLevelRoute.name) },
                        selected = currentDestination?.route == topLevelRoute.route,
                        onClick = {
                            navController.navigate(topLevelRoute.route) {
                                popUpTo(navController.graph.findStartDestination().id) {
                                    saveState = true
                                }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                }
            }
        }
    ) { innerPadding ->
        NavHost(navController, startDestination = "profile", Modifier.padding(innerPadding)) {
            composable("profile") { ProfileScreen() }
            composable("friends") { FriendsScreen() }
        }
    }
}

data class TopLevelRoute(val name: String, val route: String, val icon: ImageVector)

@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
@Composable
fun ProfileScreen() {

    var isRefreshing by rememberSaveable { mutableStateOf(false) }

    // Launch an effect when refreshing starts
    if (isRefreshing) {
        LaunchedEffect(Unit) {
            delay(10000) // Simulate a network call
            isRefreshing = false // Reset refreshing state
        }
    }

    // Content for the Profile screen
    Surface {
        PullToRefreshBox(
            onRefresh = { isRefreshing = true },
            isRefreshing = isRefreshing,
            modifier = Modifier
                .fillMaxSize()
        ) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .verticalScroll(rememberScrollState()),
                verticalArrangement = Arrangement.Center,
                horizontalAlignment = Alignment.CenterHorizontally,

                ) {
                // Your main content here
                Text("Profile Screen", style = MaterialTheme.typography.h4)
            }
        }
    }
}

@Composable
fun FriendsScreen() {
    // Content for the Friends screen
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Text("Friends Screen")
    }
}

Solution

  • It is a bug in the current stable version of material3. It is already fixed in the current alpha version 1.4.0-alpha02, I think by this commit.

    So if you want to check it out, you can change androidx.compose:compose-bom dependency to androidx.compose:compose-bom-alpha.