https://kotlinlang.org logo
#compose
Title
# compose
s

Satyam G

05/10/2022, 9:04 AM
Can we give Animation to a Card which will display and give a visual like SnackBar is displayed. How to achieve this SnackBar kind of Animation ??
f

Filip Wiesner

05/10/2022, 9:09 AM
s

Satyam G

05/10/2022, 9:10 AM
Tried. But it is not giving the visual
r

Ronald Wolvers

05/10/2022, 9:10 AM
Is this what you're referring to?
Copy code
val snackbarVisibleState = remember {
        mutableStateOf(false)
    }

    AnimatedVisibility(snackbarVisibleState.value) {
        Snackbar() {
            //Your snackbar content here...
        }
        LaunchedEffect(snackbarVisibleState) {
            //Display the snackbar for 5 seconds.
            delay(5000L)
            snackbarVisibleState.value = false
        }
    }
This will display a snackbar for 5 seconds and then animated out
Have to do the content yourself
f

Filip Wiesner

05/10/2022, 9:11 AM
it is not giving the visual
You can tweak the
enter
and
exit
transitions to achieve the animation you want.
s

Satyam G

05/10/2022, 9:11 AM
I am not using Snackbar . Just a Normal Card and some content within its scope
r

Ronald Wolvers

05/10/2022, 9:12 AM
Well, you can also use another component, the interesting parts are the
AnimatedVisibility
and
LaunchedEffect
. That's as snackbar-like as it gets if you ask me 🙂
s

Satyam G

05/10/2022, 9:12 AM
Copy code
AnimatedVisibility(
    visible = isVisible,
    enter = slideInVertically() + fadeIn(),
    exit = slideOutVertically() + fadeOut()
) {
    Card(
        elevation = 6.dp,
        modifier = Modifier
            .padding(16.dp)
            .defaultMinSize(minHeight = 48.dp),
        backgroundColor = Theme.colors.red,
        shape = Theme.roundShapes.large
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically
        ) {
            Row(
                modifier = Modifier
                    .weight(8f)
                    .padding(8.dp),
                horizontalArrangement = Arrangement.spacedBy(12.dp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                icon?.let {
                    Icon(
                        imageVector = icon,
                        tint = Theme.colors.onRed,
                        contentDescription = "",
                    )
                }
                Text(
                    text = message,
                    color = Theme.colors.onRed,
                    style = Theme.typography.bodyMedium
                )
            }
            if (action != null) {
                TextButton(
                    modifier = Modifier
                        .weight(2f),
                    onClick = action,
                    text = actionLabel,
                    containerColor = Theme.colors.red,
                    contentColor = Theme.colors.onRed,
                )
            }
        }
    }
}
My use case is only to have visual like Snackbar is displayed. Not like it should dismiss after some time 🙂
f

Filip Wiesner

05/10/2022, 9:14 AM
I am not using Snackbar . Just a Normal Card
If you look at the
Snackbar
implementation it is really simmilar to a
Card
. Both use
Surface
so there is really no difference.
And what is the problem with your implementation? What does "it is not giving the visual" mean?
s

Satyam G

05/10/2022, 9:16 AM
When it is displayed it does not look like Snackbar is displayed. Feels like Just a view becomes visible and gone
f

Filip Wiesner

05/10/2022, 9:18 AM
Can you show us the code where you change the
isVisible
boolean?
s

Satyam G

05/10/2022, 9:20 AM
Copy code
@Composable
fun Error(
    actionLabel: String = stringResource(id = R.string.lbl_reload),
    icon: ImageVector? = <http://Icons.Outlined.Info|Icons.Outlined.Info>,
    message: String = stringResource(id = R.string.lbl_error),
    action: (() -> Unit)? = null,
    isVisible: Boolean = true 
) {
    Box(modifier = Modifier.fillMaxSize(), Alignment.BottomCenter) {
        AnimatedVisibility(
            visible = isVisible,
            enter = slideInVertically() + fadeIn(),
            exit = slideOutVertically() + fadeOut()
        ) {
            Card(
                elevation = 6.dp,
                modifier = Modifier
                    .padding(16.dp)
                    .defaultMinSize(minHeight = 48.dp),
                backgroundColor = ApnaTheme.colors.red,
                shape = ApnaTheme.roundShapes.large
            ) {
                Row(
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Row(
                        modifier = Modifier
                            .weight(8f)
                            .padding(8.dp),
                        horizontalArrangement = Arrangement.spacedBy(12.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        icon?.let {
                            Icon(
                                imageVector = icon,
                                tint = Theme.colors.onRed,
                                contentDescription = "",
                            )
                        }
                        Text(
                            text = message,
                            color = Theme.colors.onRed,
                            style = Theme.typography.bodyMedium
                        )
                    }
                    if (action != null) {
                        TextButton(
                            modifier = Modifier
                                .weight(2f),
                            onClick = action,
                            text = actionLabel,
                            containerColor = ApnaTheme.colors.red,
                            contentColor = ApnaTheme.colors.onRed,
                        )
                    }
                }
            }
        }
    }
}
Copy code
var error by remember { mutableStateOf(false) }


if(error){
    Error(isVisible = error, action = {
        error = false
    })
}
Using this Error composable in one of my composable 👆way
f

Filip Wiesner

05/10/2022, 9:24 AM
Yeah, so when the error changes from
true
to
false
you just remove the whole
AnimatedVisibility
composable. How do you expect it to animate if you remove it as soon as you change the visibility boolean.
s

Satyam G

05/10/2022, 9:25 AM
What changes are expected here ? @Filip Wiesner
f

Filip Wiesner

05/10/2022, 9:26 AM
AnimatedVisibility
expects that you change the
visible
parameter. But you just remove the whole composable and create it again when there is error.
s

Satyam G

05/10/2022, 9:28 AM
oops. ☹️ So it should be like the Composable should be already displayed . The only parameter will change is the visibility
f

Filip Wiesner

05/10/2022, 9:29 AM
Yes
s

Satyam G

05/10/2022, 9:30 AM
Cool. Will modify it accordingly . 😌 Thanks for immediate response. By any chance if you have any sample implementation, please share 😊
👌 1
@Filip Wiesner One last Question out of excitement, does this animation by default runs on different thread when performed or we have to take care of performing it in different coroutine scope etc while using it
f

Filip Wiesner

05/10/2022, 10:04 AM
You don't have to @ me every time you add a message to a thread I am part of. And you just change a boolean. There is not even a way for you to manage the thread it runs on.
s

Satyam G

05/10/2022, 10:05 AM
Okay 👍
5 Views