0

I've got the following animation:

enter image description here

The problem is:

  • When animation's starting the search icon (magnifier) slides immediately to the left of the screen.

  • When the search bar is folding back the icon moves smoothly and near the end speed up.

What I want to achieve here is to make this icon slides more smoothly for a better experience.

Is there any way to achieve that?

Code responsible for animation:

IconButton(onClick = {
    isSearchEnabled = !isSearchEnabled
}) {
    Icon(Icons.Default.Search, "search")
}
AnimatedVisibility(
    visible = isSearchEnabled,
    enter = fadeIn(
        animationSpec = tween(durationMillis = 300)
    ) + slideInHorizontally(
        initialOffsetX = { it / 2 },
        animationSpec = tween(durationMillis = 700)
    ),
    exit = fadeOut(
        animationSpec = tween(300, easing = FastOutLinearInEasing)
    ) + shrinkHorizontally(
        shrinkTowards = Alignment.End,
        animationSpec = tween(durationMillis = 700, easing = FastOutLinearInEasing)
    )
) {

    TextField(
        modifier = Modifier.padding(end = 16.dp),
        shape = RoundedCornerShape(10.dp),
        value = text,
        onValueChange = { text = it; onValueChange(it) })
}
Abhimanyu
  • 11,351
  • 7
  • 51
  • 121
amtrax
  • 466
  • 7
  • 20

1 Answers1

3

This would expand and shrink the search bar,

enter image description here

@ExperimentalAnimationApi
@Composable
fun ExpandableSearchbar() {
    var text by remember {
        mutableStateOf("")
    }
    var isSearchEnabled by remember {
        mutableStateOf(false)
    }
    val slow = 700
    val fast = 300
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.End,
        modifier = Modifier
            .fillMaxWidth()
            .background(Color(0xFFE2E2E2))
            .height(120.dp),
    ) {
        IconButton(
            onClick = {
                isSearchEnabled = !isSearchEnabled
            },
        ) {
            Icon(Icons.Default.Search, "search")
        }

        AnimatedVisibility(
            visible = isSearchEnabled,
            enter = fadeIn(
                animationSpec = tween(durationMillis = fast)
            ) + expandHorizontally(
                expandFrom = Alignment.End,
                animationSpec = tween(
                    durationMillis = slow,
                    easing = FastOutLinearInEasing,
                )
            ),
            exit = fadeOut(
                animationSpec = tween(
                    durationMillis = slow,
                    easing = FastOutLinearInEasing,
                )
            ) + shrinkHorizontally(
                shrinkTowards = Alignment.End,
                animationSpec = tween(
                    durationMillis = slow,
                    easing = FastOutLinearInEasing,
                )
            )
        ) {
            TextField(
                modifier = Modifier.padding(end = 16.dp),
                shape = RoundedCornerShape(10.dp),
                value = text,
                onValueChange = {
                    text = it
                },
            )
        }
    }
}
Abhimanyu
  • 11,351
  • 7
  • 51
  • 121
  • Thanks for your commitment :) It works exactly how I've imagined it, thanks a lot! – amtrax Nov 17 '21 at 19:52
  • Glad, It helps – Abhimanyu Nov 17 '21 at 19:56
  • @ Abhimanyu If I replace the search icon with another composable (for example a card with user name and avatar) then the animation does not work. Maybe there is something wrong with the width of the other composable? I use wrapContentSize() – ziselos Aug 17 '23 at 11:38