0

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

Semerkosa
  • 16
  • 5
  • 1
    The NavHost does default to a cross fade animation between screens, but that _is_ a smooth transition. Is it the content of your screens that is flickering? What happens if you replace the contents of your screen with something static (e.g., just some placeholder text, etc.)? This seems like an issue with the implementation of your screen, which you haven't shared. – ianhanniballake Jul 05 '23 at 15:55
  • I just added how I implement my screens, which all have the same background image. I can add a very short video to show exactly how the screen is *flashing* – Semerkosa Jul 06 '23 at 07:46
  • What color is the `windowBackground` of your activity? A crossfade involves both screens being semi-transparent by definition, so you will see the underlying `windowBackground` color...which I assume is the default bright white? – ianhanniballake Jul 06 '23 at 13:35
  • It must be the default white as I haven't changed it myself. I've tried setting it to the same background image the other screens have, but it didn't change a thing. – Semerkosa Jul 07 '23 at 07:27

1 Answers1

0
  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)
            }
zaid khan
  • 825
  • 3
  • 11
  • It does work the way you described in the first possible solution. As for your second idea, this might be a thing. All my content views have the same background image, but nothing is set to the initial activity. – Semerkosa Jul 06 '23 at 07:27
  • did any of the changes work in your case? – zaid khan Jul 06 '23 at 08:22
  • With my previous comment I meant that I do use ```ChildComponents``` (I edited the question to make it more clear). I am not sure, though, how to change the ```Activity``` color as the other screens use a background image (please see the changes in the question). Thanks in advance for your help! – Semerkosa Jul 06 '23 at 08:54
  • then please consider accepting or atleast upvoting the answer – zaid khan Jul 06 '23 at 08:55
  • No solution is found. You bet I will if we do find such. :) – Semerkosa Jul 06 '23 at 09:05
  • try the edited answer – zaid khan Jul 06 '23 at 09:15
  • Where/When should I specifically execute this ```LaunchedEffect```? I've tried in both the *MainActivity.kt* and in the ```ChildComposable```s, but to no avail. – Semerkosa Jul 06 '23 at 09:49
  • both the lines inside of the setContent block of your main activity – zaid khan Jul 06 '23 at 10:10
  • That's what I thought, but it didn't work out. :( You can even check the video I added in the question. – Semerkosa Jul 06 '23 at 10:58
  • I cannot find any other solution to it :___( – zaid khan Jul 06 '23 at 15:00