skydoves / Cloudy

☁️ Jetpack Compose blur effect library, which falls back onto a CPU-based implementation to support older API levels.
Apache License 2.0
840 stars 30 forks source link

When navigate from one screen to another screen, the new screen show the previous screen as an image above the root view in the compose screen #6

Closed AlaaEddinAlbarghoth closed 4 months ago

AlaaEddinAlbarghoth commented 1 year ago

The issue I put Cloudy() above the column I used in Screen B, but when navigating from Screen A to Screen B, the previous screen A is showing in screen B

Expected Behavior: You can navigate to the new screen and you can see the views and compostables of new screen B

skydoves commented 1 year ago

Hey, thanks for reporting the issue. Which way do you use for navigating screens?

AlaaEddinAlbarghoth commented 1 year ago

Thanks, similar to this https://www.youtube.com/watch?v=gNzPGI9goU0&ab_channel=Stevdza-San

AlaaEddinAlbarghoth commented 1 year ago

Hello @skydoves, Do you have updates on this issue?

skydoves commented 1 year ago

@AlaaEddinAlbarghoth Sorry for the late response. Could you give key1 on your Cloudy composable like the example below?

Cloudy(
  radius = 15,
  key1 = (an object that indicates navigation screen, which must differ depending on your screen)
) {
  ...
}
carlospinia commented 1 year ago

Same issue here. I have been trying things out. Seeing your comment above, I tried adding a state change via a delay and it works, but during the delay you still see the previous screen in the Cloudy container.

val coroutineScope = rememberCoroutineScope()
var state by remember { mutableStateOf(0) }
LaunchedEffect(key1 = Unit) {
        coroutineScope.launch {
                delay(200)
                state = 1
        }
}
Cloudy(radius = 25, key1 = state) {
   ...
}
nubpro commented 1 year ago

@skydoves Is there a simple and elegant way to go about this?

marcopla99 commented 11 months ago

It's quite tricky to fix this issue from Cloudy because the blur is applied to a Bitmap generated from the View with a PixelCopy request on the Window. When navigating, the old screen is still visible for a few milliseconds due to the navigation animation. PixelCopy will start generating the Bitmap as soon as the navigation starts, causing the old blurred View to be shown.

One workaround to this is disabling navigation animations from your NavHost or your screen composables (only from version 2.7.0 of androidx.navigation:navigation-compose): NavHost( navController = navController, startDestination = "home", enterTransition = { EnterTransition.None }, exitTransition = { ExitTransition.None } ) { /* ... */ }

DaChelimo commented 5 months ago

Borrowed this snippet from @carlospinia. I'm implementing the View Profile Picture feature on a chat app I'm making and I was trying to replicate the Instagram profile picture view (that blurs the entire background). This weirdly worked for me {tbh, I don't know why or how... but yeahhh}

@Composable
fun ControlBlurOnScreen(
    isPictureOnFullScreen: Boolean,
    profilePic: String?,
    dismissPicture: () -> Unit,
    content: @Composable (BoxScope) -> Unit
) {
    Box(Modifier.fillMaxSize()) {
        if (isPictureOnFullScreen) {
            val coroutineScope = rememberCoroutineScope()
            var state by remember { mutableIntStateOf(0) }
            LaunchedEffect(key1 = Unit) {
                coroutineScope.launch {
                    state = 1
                }
            }

            Cloudy(
                radius = 25,
                key1 = state,
            ) {
                content(this)
            }
        }
        else
            content(this)
skydoves commented 4 months ago

Hey guys, the new version 0.2.0 has been released, and now you can resolve this issue by using the Modifier.cloudy modifier instead of the Cloudy composable function.