What's the best way to create a smooth alpha fade ...
# compose
l
What's the best way to create a smooth alpha fade animation ? For example, I want my TopAppBar backgroundColor alpha to be updated while the user is scrolling. Depending of the scrolling speed, the animateFloatAsState isn't updated as much as wanted. I have to scroll very slowly to have something not too bad. Is there a better way ? Code & video of the animation in thread
Copy code
val scrollState = rememberScrollState()
BoxWithConstraints {

            val partScreen = 3 //screen divider, as the header is an image taking a third of the screen
            val offset = (scrollState.value / partScreen)
            val offsetDp = with(LocalDensity.current) { offset.toDp() }
            val maxHeight = this@BoxWithConstraints.maxHeight / partScreen

            val tobAppBarBackgroundColorAlpha: Float by animateFloatAsState(
                when (scrollState.value) {
                    0f -> {
                        0f
                    }
                    in 0f..maxHeight.value -> {
                        scrollState.value/maxHeight.value
                    }
                    else -> {
                        1f
                    }
                }
            )

            Column(modifier = Modifier
                .fillMaxSize()
                .verticalScroll(scrollState)) {
                CoilImage(
                    modifier = Modifier
                        .preferredHeightIn(max = maxHeight)
                        .fillMaxWidth()
                        .padding(top = offsetDp),
                    data = hikeDetail.picture,
                    contentScale = ContentScale.Crop,
                    contentDescription = null
                )
                ... // content of screen
            }

            TopAppBar(
                modifier = Modifier
                    .fillMaxWidth()
                    .statusBarsPadding(),
                title = {},
                backgroundColor = Color.White.copy(alpha = tobAppBarBackgroundColorAlpha),
                elevation = 0.dp,
                contentColor = MaterialTheme.colors.onSurface,
                navigationIcon = {
                    IconButton(
                        modifier = Modifier.background(
                            color = MaterialTheme.colors.surface,
                            shape = CircleShape
                        ),
                        onClick = { onBackPressed() },
                    ) {
                        Icon(
                            painter = painterResource(id = R.drawable.ic_back),
                            contentDescription = null,
                            tint = MaterialTheme.colors.onSurface,
                        )
                    }
                }
            )
        }
here is how it looks like
t
Not clear what scrollState is. But i assume it is ScrollState. Did you tryed to use scrollState.isScrollInProgress? Also you could use animateColorAsState then you do not need to copy the color each frame.
l
yes scrollState = rememberScrollState(), I updated the code
I'm going to check animateColorAsState thx
t
And more important instead of using scrollState.value use scrollState.isScrollInProress
l
I can't find the declaration
isScrollInProress
do you mean isAnimationRunning instead ?
t
yea i think in the older versions it could be isAnimationRunning
But in compose beta01 i do have isScrollInProgress
l
Ah sorry I'm still in alpha12, waiting to finish my feature before migrating.
isScrollInProress/isAnimationRunning
is a boolean, it doesn't get the scroll value. So I'm not sure to follow
What do you have in mind ? Fetching when the scroll is happening and getting the value each time ?
t
Ok maybe i misunderstood what you try to archive. I though you want to fade out the topbar during scrolling.
l
I want the topAppBar color to change, transparent when scroll position = 0 and then smoothly going to white until the topAppBar reach the bottom of the picture
t
OK sorry.
For the calculation of the alpha you should use the maxValue from the scrollState and not from the BoxWithConstraints i think. But still not clear what you really want 😄
l
Here is the animation from iOS, I would like to create something similar for the topAppBar
t
Oh i see. I think there is a nestedScroll modifier maybe this would help.
l
Oh i see. I think there is a nestedScroll modifier maybe this would help.
Ok I will check 🙂
k
I see what you are trying to do. let me check your code and see if i can pick up something
l
hey thanks, you can check the code in top of this thread!
k
I have already ran the code in android studio and the fading in of the top app bar is not smooth. I am first checking the calculations.
l
I don't know why, but the value for scrollState.value isn't always scrolled while user is scrolling
I'm not sure if it's intended by the Compose API
g
Did you manage to complete this? And how did you make that transparent notificationbar?
l
Yeah I was able to complete the animation 🙂 it was in another thread: https://kotlinlang.slack.com/archives/CJLTWPH7S/p1614275534266700 And for the translucent notificationbar you just have to do it in your theme.xml as it's usually done in a none Compose app. But you should look for the latest release of Accompanist, they added a specific library to set the color easily: https://google.github.io/accompanist/systemuicontroller/