Extended FAB that collapses into FAB not animating correctly - Jetpack Compose (Kotlin)

78 Views Asked by At

I am trying to make an extended FAB that is fully extended when the user is at the top of the screen, but when they scroll (during the scroll) I want it to collapse into a FAB with a single icon. Right now the behavior does just that, but the animation seems to be skipped and it is almost instantaneous for the transition rather than a more subtle transition. This is my code:

package com.example.turnorder.composables.shared


import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.shrinkHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

@Composable
fun ScrollAwareFAB(
    listState: LazyGridState,
    modifier: Modifier,
    onClick: () -> Unit
) {

    var isExtended by remember { mutableStateOf(true) }



    LaunchedEffect(listState) {
            snapshotFlow { listState.firstVisibleItemScrollOffset }
                .collect {offset ->
                    isExtended = offset ==0

            }

        }


    AnimatedVisibility(
        visible = true,
        enter = expandHorizontally(expandFrom = Alignment.End),//animationSpec = tween(durationMillis = 1500, delayMillis = 1500, easing = LinearEasing)) + expandHorizontally (),
        exit = shrinkHorizontally (shrinkTowards = Alignment.End)//fadeOut(animationSpec = tween(durationMillis = 1500, delayMillis = 1500, easing = LinearEasing)) + shrinkHorizontally (),

    ) {
        Box(modifier){
            if (isExtended) {
                ExtendedFloatingActionButton(
                    text = { Text("Add Character")},
                    icon = { Icon(Icons.Filled.Add, contentDescription = "Add") },
                    onClick = { onClick },
                    containerColor = MaterialTheme.colorScheme.primary,
                    contentColor = MaterialTheme.colorScheme.onPrimary,
                )
            } else if (!isExtended){
                FloatingActionButton(
                    onClick =  {onClick},
                    containerColor = MaterialTheme.colorScheme.primary ,
                    contentColor = MaterialTheme.colorScheme.onPrimary


                ){
                    Icon(Icons.Filled.Add, contentDescription = "Add") }

            }
        }
    }

}

I have tried adding animationSpec details such as

animationSpec = tween(durationMillis = 1500, delayMillis = 1500, easing = LinearEasing)) + expandHorizontally ()

Even with an egregiously high number it does not seem to transition slower. I would really appreciate some help, I am sure I am doing something dumb.

1

There are 1 best solutions below

0
Cassie S. On

Found an easy answer to this in case others stumble on this. I did the following and it did work:

        ExtendedFloatingActionButton(
        text = { Text("Add Character")},
        icon = { Icon(Icons.Filled.Add, contentDescription = "Add") },
        onClick = { showDialog = true } ,
        containerColor = MaterialTheme.colorScheme.primaryContainer,
        contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
        expanded = isExtended,
        modifier = Modifier.align(Alignment.TopEnd).padding(top = 20.dp, end = 15.dp)
    )