英文:
Animate Column from Arrangement.Center to Arrangement.Top
问题
我正在使用Jetpack Compose原生动画来创建一个包含一些步骤的复杂过渡效果。问题是,原始的Column的排列方式被设置为居中,而在列中添加一些元素后,排列方式需要切换到顶部。如果只是改变排列方式,我希望得到一个连续的效果,而不是目前的中断。
是否有办法来动画化这种属性?
致意。
英文:
I am using Jetpack Compose native animations to create a complex transition with some steps. The issue is that the original Column has the arrangement set to Center and after the inclusion of some elements in the column, the arrangement needs to switch to Top. If I just change the arrangement, I would like a continuous effect instead of the current break.
Is there any way to animate this kind of property?
Regards.
答案1
得分: 4
可以使用Modifier.onPlaced和Modifier.offset来实现这个效果,通过创建一个Modifier函数来实现:
fun Modifier.animatePlacement(): Modifier = composed {
val scope = rememberCoroutineScope()
var targetOffset by remember { mutableStateOf(IntOffset.Zero) }
var animatable by remember {
mutableStateOf<Animatable<IntOffset, AnimationVector2D>?>(null)
}
this
// 🔥 onPlaced should be before offset Modifier
.onPlaced {
// Calculate the position in the parent layout
targetOffset = it
.positionInParent()
.round()
}
.offset {
// Animate to the new target offset when alignment changes.
val anim = animatable ?: Animatable(targetOffset, IntOffset.VectorConverter)
.also {
animatable = it
}
if (anim.targetValue != targetOffset) {
scope.launch {
anim.animateTo(targetOffset, spring(stiffness = Spring.StiffnessMediumLow))
}
}
// Offset the child in the opposite direction to the targetOffset, and slowly catch
// up to zero offset via an animation to achieve an overall animated movement.
animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
}
}
这是一个用于修改Composable的Modifier,可以使用在以下的Composable中:
@Composable
fun AnimatedChildArrangement(arrangement: Arrangement.Vertical) {
Column(
Modifier
.fillMaxSize()
.padding(4.dp)
.border(2.dp, Color.Green),
verticalArrangement = arrangement
) {
Box(
modifier = Modifier
.animatePlacement()
.size(100.dp)
.background(Color.Red)
)
}
}
你可以在Demo中使用这个Composable来测试效果:
@Preview
@Composable
private fun Test() {
var arrangement: Arrangement.Vertical by remember {
mutableStateOf(Arrangement.Center)
}
Column {
Button(onClick = {
arrangement = if (arrangement == Arrangement.Center) {
Arrangement.Top
} else {
Arrangement.Center
}
}) {
Text(text = "arrangement: $arrangement")
}
AnimatedChildArrangement(arrangement = arrangement)
}
}
以上是你要翻译的部分。
英文:
It can be done with Modifier.onPlaced and Modifier.offset by creating a Modifier
fun Modifier.animatePlacement(): Modifier = composed {
val scope = rememberCoroutineScope()
var targetOffset by remember { mutableStateOf(IntOffset.Zero) }
var animatable by remember {
mutableStateOf<Animatable<IntOffset, AnimationVector2D>?>(null)
}
this
// 🔥 onPlaced should be before offset Modifier
.onPlaced {
// Calculate the position in the parent layout
targetOffset = it
.positionInParent()
.round()
}
.offset {
// Animate to the new target offset when alignment changes.
val anim = animatable ?: Animatable(targetOffset, IntOffset.VectorConverter)
.also {
animatable = it
}
if (anim.targetValue != targetOffset) {
scope.launch {
anim.animateTo(targetOffset, spring(stiffness = Spring.StiffnessMediumLow))
}
}
// Offset the child in the opposite direction to the targetOffset, and slowly catch
// up to zero offset via an animation to achieve an overall animated movement.
animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
}
}
Some Composable that this modifier is assigned to
@Composable
fun AnimatedChildArrangement(arrangement: Arrangement.Vertical) {
Column(
Modifier
.fillMaxSize()
.padding(4.dp)
.border(2.dp, Color.Green),
verticalArrangement = arrangement
) {
Box(
modifier = Modifier
.animatePlacement()
.size(100.dp)
.background(Color.Red)
)
}
}
Demo
@Preview
@Composable
private fun Test() {
var arrangement: Arrangement.Vertical by remember {
mutableStateOf(Arrangement.Center)
}
Column {
Button(onClick = {
arrangement = if (arrangement == Arrangement.Center) {
Arrangement.Top
} else {
Arrangement.Center
}
}) {
Text(text = "arrangement: $arrangement")
}
AnimatedChildArrangement(arrangement = arrangement)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论