Jetpack Compose 中的 MotionLayout

4

这可能有点早,但应该有一种解决方法。

TL;DR

有没有办法在MotionLayout中使用Jetpack ComposeComposable组件?
这种组合是否在MotionLayout或Compose的路线图中?


在Jetpack Compose中是否有类似的替代方案可以做到相同的效果?

由于任何想要在运动场景中进行修改的视图,Compose函数无法在运动场景中修改。

问题

我想要在Surface的中心动画一个图片,并在特定时间内缩放它。

使用motion,您可以在每个步骤中定义关键帧。

UI使用Composable函数制作如何在Compose中实现我以前在MotionLayout中所做的操作?


Jetpack compose: v1.0.0-alpha02

2个回答

5
你应该使用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))
            }
        }
    }
}

1
TransitionDefinition已经在Compose Animation Version 1.0.0-alpha11中被弃用。现在你使用什么? - pommy
https://developer.android.com/jetpack/compose/animation - gMale

2

最新版的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")
        }
    }
}

您可以在这个维基页面约束布局存储库中阅读更多信息并跟踪进展。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接