简体   繁体   English

Jetpack Compose - 无法为脚手架底部栏的高度设置动画

[英]Jetpack Compose - Cannot animate Scaffold's bottom bar's height

I need to reveal some floating action buttons at the bottom of the screen when some other buttons, in a scrollable list, are no longer visible on the screen.当可滚动列表中的其他一些按钮在屏幕上不再可见时,我需要在屏幕底部显示一些浮动操作按钮。 Naturally, I feel like using LazyColumn , AnimatedVisibility and Scaffold 's bottom bar for this (I need the snackbar and the screen's content be above the floating action buttons).自然,我想为此使用LazyColumnAnimatedVisibilityScaffold的底部栏(我需要小吃栏和屏幕的内容位于浮动操作按钮上方)。 But the animation doesn't work as expected.但是 animation 不能按预期工作。 As the floating buttons appear/dissapear, the bottom bar's height is not animated (but I think it could actually be that the content padding isn't animated).随着浮动按钮的出现/消失,底部栏的高度没有动画(但我认为实际上可能是内容填充没有动画)。

The result I'm getting:我得到的结果:

在此处输入图像描述

The code:编码:

val lazyListState = rememberLazyListState()
val isFloatingButtonVisible by derivedStateOf {
    lazyListState.firstVisibleItemIndex >= 2
}
Scaffold(
    bottomBar = {
        AnimatedVisibility(
            visible = isFloatingButtonVisible,
            enter = slideInVertically { height -> height },
            exit = slideOutVertically { height -> height }
        ) {
            Row(
                modifier = Modifier.padding(8.dp),
                horizontalArrangement = Arrangement.spacedBy(8.dp)
            ) {
                repeat(2) {
                    Button(
                        modifier = Modifier
                            .height(48.dp)
                            .weight(1f),
                        onClick = {}
                    ) {
                        Text(text = "Something")
                    }
                }
            }
        }
    }
) { contentPadding ->
    LazyColumn(
        modifier = Modifier.padding(contentPadding),
        state = lazyListState,
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        item {
            Text(
                text = LoremIpsum(50).values.joinToString(" ")
            )
        }
        item {
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                repeat(2) {
                    Button(onClick = {}) {
                        Text(text = "Bla Bla")
                    }
                }
            }
        }
        item {
            Text(
                text = LoremIpsum(700).values.joinToString(" ")
            )
        }
    }
}

The content padding in lazycolumn modifier breaks the animation; lazycolumn 修饰符中的内容填充破坏了 animation;

LazyColumn(
   modifier = Modifier.padding(contentPadding) // -> Delete this.
)

For the same view;出于同样的看法;

Row(
   modifier = Modifier
      .background(Color.White) //-> Add this.
      .padding(8.dp) 
)

I don't think it's possible to do this with AnimatedVisibility .我认为用AnimatedVisibility不可能做到这一点。 I got it like this我得到它是这样的

val bottomBarHeight = (48 + 8 * 2).dp // button height + paddings

@Composable
fun Test() {
    val lazyListState = rememberLazyListState()

    val isFloatingButtonVisible by derivedStateOf {
        lazyListState.firstVisibleItemIndex >= 1
    }

    val offset by animateDpAsState(if (isFloatingButtonVisible) bottomBarHeight else 0.dp)

    BoxWithConstraints(Modifier.fillMaxSize()) {
        LazyColumn(
            modifier = Modifier
                .size(width = maxWidth, height = maxHeight - offset)
                .background(Color.Yellow),
            state = lazyListState,
            contentPadding = PaddingValues(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            repeat(15) {
                item {
                    Text(
                        text = LoremIpsum(50).values.joinToString(" ")
                    )
                }
            }
        }

        Row(
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .offset(0.dp, -offset + bottomBarHeight)
                .background(Color.Green)
                .padding(8.dp),
            horizontalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            repeat(2) {
                Button(
                    modifier = Modifier
                        .height(48.dp)
                        .weight(1f),
                    onClick = {}
                ) {
                    Text(text = "Something")
                }
            }
        }
    }
}

Got the right result using AnimatedContent instead of AnimatedVisibility .使用AnimatedContent而不是AnimatedVisibility得到了正确的结果。

在此处输入图像描述

val lazyListState = rememberLazyListState()
val isFloatingButtonVisible by derivedStateOf {
    lazyListState.firstVisibleItemIndex >= 2
}
Scaffold(
    bottomBar = {
        AnimatedContent(
            targetState = isFloatingButtonVisible,
            transitionSpec = {
                slideInVertically { height -> height } with
                slideOutVertically { height -> height }
            }
        ) { isVisible ->
            if (isVisible) {
                Row(
                    modifier = Modifier
                        .border(1.dp, Color.Red)
                        .padding(8.dp),
                    horizontalArrangement = Arrangement.spacedBy(8.dp)
                ) {
                    repeat(2) {
                        Button(
                            modifier = Modifier
                                .height(48.dp)
                                .weight(1f),
                            onClick = {}
                        ) {
                            Text(text = "Something")
                        }
                    }
                }
            } else {
                Box(modifier = Modifier.fillMaxWidth())
            }
        }
    }
) { contentPadding ->
    LazyColumn(
        modifier = Modifier.padding(contentPadding),
        state = lazyListState,
        contentPadding = PaddingValues(16.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        item {
            Text(
                text = LoremIpsum(50).values.joinToString(" ")
            )
        }
        item {
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                repeat(2) {
                    Button(onClick = {}) {
                        Text(text = "Bla Bla")
                    }
                }
            }
        }
        item {
            Text(
                text = LoremIpsum(700).values.joinToString(" ")
            )
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM