Semerkosa
Semerkosa

Reputation: 126

Is there a way to remove screen flashing (flickering) when using NavHostController with Kotlin in Android

I am working on an Android application using Kotlin and Jetpack Compose. To switch between the different screens I am using the NavHostController.

Initialization:

private lateinit var navController: NavHostController

setContent {
    navController = rememberNavController()

    Theme {
        ...
    }
}

Usage:

NavHost(navController = navController, startDestination = *route*) {
    composable(route = *route*) {

    }

    composable(route = *route*) {

    }

    ...
}

In each composable I call navController.navigate(route = *route*) to switch between screens.

EDIT ( I call the navController.navigate() inside a ChildComposable, which is inside the composable).

I use one Activity only, which has no background set. This is how I add a background image to all the screens:

@Composable
fun ContentWithBackground(
    content: @Composable () -> Unit
) = Box(modifier = Modifier.fillMaxSize()) {

    Image(
        painter = rememberAsyncImagePainter(model = R.drawable.background),
        contentDescription = "Logo",
        contentScale = ContentScale.Crop,
        modifier = Modifier.fillMaxSize()
    )

    content()
}

The way I use the navigation causes flashing when the screens are changed and the new content is replacing the previous one. Basically, flickering. I guess this is somewhat of an expected behaviour.

However, is there a way to fix this? How can the change happen smoothly?

Here is a video of the flashing:

Video hosted in streamable.com

Upvotes: 2

Views: 987

Answers (1)

zaid khan
zaid khan

Reputation: 1012

  1. Don't pass the nav controller to your child composables instead hoist the state and navigate from the main activity.
NavHost(navController = navController, startDestination = *route*) {
    composable(route = *route*) {

        ChildComposable{
             navController.navigate("")
           }
    }

    composable(route = *route*) {

    }

    ...
}

@Composable
fun ChildComposable(
  navigate : () -> Unit
){
   Button(
    onClick = { navigate() }
   ){
  Text(text = "exit")
 }
} 
  1. Another reason can be that the background color of your activity differs from the composable's background color,you can remove the background from the composable and add it to the activity window.

EDIT

to change activity's background to an image you can use this

val activity = LocalContext.current as Activity
            LaunchedEffect(activity) {
                activity.window.setBackgroundDrawableResource(R.drawable.img)
            }

Upvotes: 1

Related Questions