Jetpack Compose 中的 MotionLayout
MotionLayout in Jetpack Compose
This might be a little soon, but there should be a workaround for this
TL;DR
有没有办法在 MotionLayout 中使用 Jetpack Compose 的 Composable 组件?
MotionLayout 或 Compose 的路线图中有这样的组合吗?
在 Jetpack compose 中是否有替代品可以实现同样的功能?
由于任何view想在motion scene中修改,compose函数在motion scene中是不能修改的。
问题
我想在 Surface
的中心设置一个图像的动画,并在特定的持续时间内放大和缩小它。
使用动画,您可以在每个步骤中定义关键帧。
Ui 是使用 Composable 函数 制作的。 如何使用 Compose 中的 MotionLayout 完成我能做的事情?
Jetpack 组合:v1.0.0-alpha02
你应该使用transitionDefinition
,检查下面的例子并根据你的需要采用它。
enum class State {
A, B
}
private val scale = FloatPropKey()
private val definition = transitionDefinition {
state(State.A) {
this[scale] = 1f
}
state(State.B) {
this[scale] = 5f
}
transition(fromState = State.A, toState = State.B) {
scale using tween(
durationMillis = 3000,
easing = FastOutSlowInEasing
)
}
}
@Composable
fun AnimateComponentScale() {
var initialState by remember { mutableStateOf(State.A) }
var toState by remember { mutableStateOf(State.B) }
val state = transition(
definition = definition,
initState = initialState,
toState = toState
) { state ->
when (state) {
State.A -> {
initialState = State.A
toState = State.B
}
State.B -> {
initialState = State.B
toState = State.A
}
}
}
Box(
modifier = Modifier.fillMaxSize(),
gravity = ContentGravity.Center,
backgroundColor = Color.Cyan
) {
Canvas(modifier = Modifier.preferredSize(50.dp)) {
scale(scaleX = state[scale], scaleY = state[scale]) {
drawRect(color = Color(255, 138, 128))
}
}
}
}
您现在可以使用最新版本的 constraintlayout-compose(撰写本文时 1.0.0-beta02
)在 Compose 中使用 MotionLayout
功能方向的子集。
文档中的说明显示您可以将其添加到您的项目中:
dependencies {
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02")
}
文档还提供了一个在两个约束集之间转换的简单示例:
@Preview(group = "motion8")
@Composable
public fun AttributesRotationXY() {
var animateToEnd by remember { mutableStateOf(false) }
val progress by animateFloatAsState(
targetValue = if (animateToEnd) 1f else 0f,
animationSpec = tween(6000)
)
Column {
MotionLayout(
modifier = Modifier
.fillMaxWidth()
.height(400.dp)
.background(Color.White),
motionScene = MotionScene("""{
ConstraintSets: { // all ConstraintSets
start: { // constraint set id = "start"
a: { // Constraint for widget id='a'
width: 40,
height: 40,
start: ['parent', 'start', 16],
bottom: ['parent', 'bottom', 16]
}
},
end: { // constraint set id = "start"
a: {
width: 40,
height: 40,
//rotationZ: 390,
end: ['parent', 'end', 16],
top: ['parent', 'top', 16]
}
}
},
Transitions: { // All Transitions in here
default: { // transition named 'default'
from: 'start', // go from Transition "start"
to: 'end', // go to Transition "end"
pathMotionArc: 'startHorizontal', // move in arc
KeyFrames: { // All keyframes go here
KeyAttributes: [ // keyAttributes key frames go here
{
target: ['a'], // This keyAttributes group target id "a"
frames: [25,50,75], // 3 points on progress 25% , 50% and 75%
rotationX: [0, 45, 60], // the rotationX angles are a spline from 0,0,45,60,0
rotationY: [60, 45, 0], // the rotationX angles are a spline from 0,60,45,0,0
}
]
}
}
}
}"""),
debug = EnumSet.of(MotionLayoutDebugFlags.SHOW_ALL),
progress = progress) {
Box(modifier = Modifier
.layoutId("a")
.background(Color.Red))
}
Button(onClick = { animateToEnd = !animateToEnd }) {
Text(text = "Run")
}
}
}
您可以阅读更多内容并关注 this wiki and the constraint layout repository 中的进展。
This might be a little soon, but there should be a workaround for this
TL;DR
有没有办法在 MotionLayout 中使用 Jetpack Compose 的 Composable 组件?
MotionLayout 或 Compose 的路线图中有这样的组合吗?
在 Jetpack compose 中是否有替代品可以实现同样的功能?
由于任何view想在motion scene中修改,compose函数在motion scene中是不能修改的。
问题
我想在 Surface
的中心设置一个图像的动画,并在特定的持续时间内放大和缩小它。
使用动画,您可以在每个步骤中定义关键帧。
Ui 是使用 Composable 函数 制作的。 如何使用 Compose 中的 MotionLayout 完成我能做的事情?
Jetpack 组合:v1.0.0-alpha02
你应该使用transitionDefinition
,检查下面的例子并根据你的需要采用它。
enum class State {
A, B
}
private val scale = FloatPropKey()
private val definition = transitionDefinition {
state(State.A) {
this[scale] = 1f
}
state(State.B) {
this[scale] = 5f
}
transition(fromState = State.A, toState = State.B) {
scale using tween(
durationMillis = 3000,
easing = FastOutSlowInEasing
)
}
}
@Composable
fun AnimateComponentScale() {
var initialState by remember { mutableStateOf(State.A) }
var toState by remember { mutableStateOf(State.B) }
val state = transition(
definition = definition,
initState = initialState,
toState = toState
) { state ->
when (state) {
State.A -> {
initialState = State.A
toState = State.B
}
State.B -> {
initialState = State.B
toState = State.A
}
}
}
Box(
modifier = Modifier.fillMaxSize(),
gravity = ContentGravity.Center,
backgroundColor = Color.Cyan
) {
Canvas(modifier = Modifier.preferredSize(50.dp)) {
scale(scaleX = state[scale], scaleY = state[scale]) {
drawRect(color = Color(255, 138, 128))
}
}
}
}
您现在可以使用最新版本的 constraintlayout-compose(撰写本文时 1.0.0-beta02
)在 Compose 中使用 MotionLayout
功能方向的子集。
文档中的说明显示您可以将其添加到您的项目中:
dependencies {
implementation("androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02")
}
文档还提供了一个在两个约束集之间转换的简单示例:
@Preview(group = "motion8")
@Composable
public fun AttributesRotationXY() {
var animateToEnd by remember { mutableStateOf(false) }
val progress by animateFloatAsState(
targetValue = if (animateToEnd) 1f else 0f,
animationSpec = tween(6000)
)
Column {
MotionLayout(
modifier = Modifier
.fillMaxWidth()
.height(400.dp)
.background(Color.White),
motionScene = MotionScene("""{
ConstraintSets: { // all ConstraintSets
start: { // constraint set id = "start"
a: { // Constraint for widget id='a'
width: 40,
height: 40,
start: ['parent', 'start', 16],
bottom: ['parent', 'bottom', 16]
}
},
end: { // constraint set id = "start"
a: {
width: 40,
height: 40,
//rotationZ: 390,
end: ['parent', 'end', 16],
top: ['parent', 'top', 16]
}
}
},
Transitions: { // All Transitions in here
default: { // transition named 'default'
from: 'start', // go from Transition "start"
to: 'end', // go to Transition "end"
pathMotionArc: 'startHorizontal', // move in arc
KeyFrames: { // All keyframes go here
KeyAttributes: [ // keyAttributes key frames go here
{
target: ['a'], // This keyAttributes group target id "a"
frames: [25,50,75], // 3 points on progress 25% , 50% and 75%
rotationX: [0, 45, 60], // the rotationX angles are a spline from 0,0,45,60,0
rotationY: [60, 45, 0], // the rotationX angles are a spline from 0,60,45,0,0
}
]
}
}
}
}"""),
debug = EnumSet.of(MotionLayoutDebugFlags.SHOW_ALL),
progress = progress) {
Box(modifier = Modifier
.layoutId("a")
.background(Color.Red))
}
Button(onClick = { animateToEnd = !animateToEnd }) {
Text(text = "Run")
}
}
}
您可以阅读更多内容并关注 this wiki and the constraint layout repository 中的进展。