Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Introduction to MotionLayout in Compose

John Hoford edited this page Jul 30, 2021 · 8 revisions

For those new to MotionLayout.

MotionLayout's core engine allows you to interpolate between two constraintSet With Transitions and keyframes controlling the transitions.

<SideNote:
The full MotionLayout has many features (See ConstraintLayout 2.1)
The first release of MotionLayout in ConstraintLayoutCompose 1.0 focuses on a limited subset using the json syntax.
The hope is that users will provide feedback to allow us to tailor the API to developer needs. 

MotionLayout for Compose takes on of:

  • Two ConstraintsSet (start & end), a Transition, and progress
  • A MotionScene and progress

See Introduction to ConstraintLayout for more details on ConstraintSets

fun MotionLayout(
    start: ConstraintSet,
    end: ConstraintSet,
    transition: androidx.constraintlayout.compose.Transition? = null,
    progress: Float,
    debug: EnumSet<MotionLayoutDebugFlags> = EnumSet.of(MotionLayoutDebugFlags.NONE),
    modifier: Modifier = Modifier,
    optimizationLevel: Int = Optimizer.OPTIMIZATION_STANDARD,
    crossinline content: @Composable MotionLayoutScope.() -> Unit
) {}
fun MotionLayout(
    motionScene: MotionScene,
    progress: Float,
    debug: EnumSet<MotionLayoutDebugFlags> = EnumSet.of(MotionLayoutDebugFlags.NONE),
    modifier: Modifier = Modifier,
    optimizationLevel: Int = Optimizer.OPTIMIZATION_STANDARD,
    crossinline content: @Composable() (MotionLayoutScope.() -> Unit),
) {}

Transition

Currently Transition Only supports a Transition String

e.g:

transition = Transition("""
            {
              KeyFrames: {
                KeyPositions: [
                {
                   target: ['a'],
                   frames: [50],
                   percentX: [0.8],
                   percentY: [0.8]
                }
                ]
              }
            }

Details on Transitions in json

MotionScene

Currently MotionScene Only supports a json syntax MotionScene JSON syntax

@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")
        }
    }
}
Clone this wiki locally