Compose AnimatedVisibility 转义容器
Compose AnimatedVisibility escapes container
我正在使用 Jetpack Compose(版本 1.1.1),我正在尝试使用 AnimatedVisibility 显示来自屏幕顶部的快餐栏式警报。但是,当我这样做时,警报会脱离其容器并与它上方的内容重叠(在本例中为操作栏)。此外,其下方的内容(按钮)会等到动画完成后再调整其位置。这会产生跳跃效果。我希望它与警报同步下滑。
@Composable
fun HomeScreen() {
val showAlert = remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
Column(Modifier.fillMaxHeight()) {
ActionBar("Home Screen")
Column {
Alert(visible = showAlert.value)
Button(modifier = Modifier.padding(16.dp), onClick = {
scope.launch {
showAlert.value = true
delay(1000)
showAlert.value = false
}
}) {
Text("Show Alert")
}
}
}
}
@Composable
private fun ActionBar(title: String) {
TopAppBar(backgroundColor = Color.Blue, contentColor = Color.White) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(start = 8.dp, end = 8.dp)) {
Text(title)
}
}
}
@Composable
fun Alert(visible: Boolean) {
AnimatedVisibility(visible = visible, enter = slideInVertically(), exit = slideOutVertically()) {
Column(Modifier.fillMaxWidth().background(Color.Red)) {
Text("An error has occurred", Modifier.padding(16.dp), style = TextStyle(Color.White))
}
}
}
@Preview
@Composable
fun HomeScreenPreview() {
Box(Modifier.fillMaxSize().background(Color.White)) {
HomeScreen()
}
}
对于重叠问题,可以使用修饰符:Modifier.clipToBounds()
对于 'jumpy effect',您可以将警告文本和页面内容放在一个列中并设置偏移动画。
enum class AlertState {
Collapsed,
Expanded
}
@Preview
@Composable
fun HomeScreen() {
val scope = rememberCoroutineScope()
val alertHeight = 40.dp
var currentState by remember { mutableStateOf(AlertState.Collapsed) }
val transition = updateTransition(currentState, label = "")
val alertOffset by transition.animateDp(label = "") {
when (it) {
AlertState.Collapsed -> -alertHeight
AlertState.Expanded -> 0.dp
}
}
Column(Modifier.fillMaxHeight()) {
TopAppBar(backgroundColor = Color.Blue, contentColor = Color.White) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(start = 8.dp, end = 8.dp)
) {
Text("Home Screen")
}
}
Column(
modifier = Modifier.clipToBounds().offset(y = alertOffset)
) {
Row(
Modifier.height(alertHeight).fillMaxWidth().background(Color.Red).padding(start = 16.dp)
) {
Text(
"An error has occurred", style = TextStyle(Color.White),
modifier = Modifier.align(Alignment.CenterVertically)
)
}
Button(modifier = Modifier.padding(16.dp), onClick = {
scope.launch {
currentState = AlertState.Expanded
delay(1000)
currentState = AlertState.Collapsed
}
}) {
Text("Show Alert")
}
}
}
}
如果您的警戒高度不固定,您可以使用修饰符Modifier.onGloballyPositioned
获得它
我正在使用 Jetpack Compose(版本 1.1.1),我正在尝试使用 AnimatedVisibility 显示来自屏幕顶部的快餐栏式警报。但是,当我这样做时,警报会脱离其容器并与它上方的内容重叠(在本例中为操作栏)。此外,其下方的内容(按钮)会等到动画完成后再调整其位置。这会产生跳跃效果。我希望它与警报同步下滑。
@Composable
fun HomeScreen() {
val showAlert = remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
Column(Modifier.fillMaxHeight()) {
ActionBar("Home Screen")
Column {
Alert(visible = showAlert.value)
Button(modifier = Modifier.padding(16.dp), onClick = {
scope.launch {
showAlert.value = true
delay(1000)
showAlert.value = false
}
}) {
Text("Show Alert")
}
}
}
}
@Composable
private fun ActionBar(title: String) {
TopAppBar(backgroundColor = Color.Blue, contentColor = Color.White) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(start = 8.dp, end = 8.dp)) {
Text(title)
}
}
}
@Composable
fun Alert(visible: Boolean) {
AnimatedVisibility(visible = visible, enter = slideInVertically(), exit = slideOutVertically()) {
Column(Modifier.fillMaxWidth().background(Color.Red)) {
Text("An error has occurred", Modifier.padding(16.dp), style = TextStyle(Color.White))
}
}
}
@Preview
@Composable
fun HomeScreenPreview() {
Box(Modifier.fillMaxSize().background(Color.White)) {
HomeScreen()
}
}
对于重叠问题,可以使用修饰符:Modifier.clipToBounds()
对于 'jumpy effect',您可以将警告文本和页面内容放在一个列中并设置偏移动画。
enum class AlertState {
Collapsed,
Expanded
}
@Preview
@Composable
fun HomeScreen() {
val scope = rememberCoroutineScope()
val alertHeight = 40.dp
var currentState by remember { mutableStateOf(AlertState.Collapsed) }
val transition = updateTransition(currentState, label = "")
val alertOffset by transition.animateDp(label = "") {
when (it) {
AlertState.Collapsed -> -alertHeight
AlertState.Expanded -> 0.dp
}
}
Column(Modifier.fillMaxHeight()) {
TopAppBar(backgroundColor = Color.Blue, contentColor = Color.White) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(start = 8.dp, end = 8.dp)
) {
Text("Home Screen")
}
}
Column(
modifier = Modifier.clipToBounds().offset(y = alertOffset)
) {
Row(
Modifier.height(alertHeight).fillMaxWidth().background(Color.Red).padding(start = 16.dp)
) {
Text(
"An error has occurred", style = TextStyle(Color.White),
modifier = Modifier.align(Alignment.CenterVertically)
)
}
Button(modifier = Modifier.padding(16.dp), onClick = {
scope.launch {
currentState = AlertState.Expanded
delay(1000)
currentState = AlertState.Collapsed
}
}) {
Text("Show Alert")
}
}
}
}
如果您的警戒高度不固定,您可以使用修饰符Modifier.onGloballyPositioned