Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Compose Layout API

Jetpack Compose Layout API

Moyuru Aizawa

February 17, 2023
Tweet

More Decks by Moyuru Aizawa

Other Decks in Programming

Transcript

  1. Moyuru Aizawa Software Engineer of Catlog, RABO. Previously at Azit,

    CyberAgent, and Eureka. Love Metal, Hardcore and EDM. MoyuruAizawa
  2. @Composable inline fun Layout( content: @Composable @UiComposable () -> Unit,

    modifier: Modifier = Modifier, measurePolicy: MeasurePolicy ) Layout API
  3. @Composable inline fun Layout( content: @Composable @UiComposable () -> Unit,

    modifier: Modifier = Modifier, measurePolicy: MeasurePolicy ) Layout API
  4. class SimpleRowMeasurePolicy : MeasurePolicy { override fun MeasureScope.measure( measurables: List<Measurable>,

    constraints: Constraints ): MeasureResult { … } } SimpleRowMeasurePolicy
  5. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } MeasurePolicy#measure
  6. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } measurables(children)Λmeasure֤ͯ͠ݸͷαΠζΛܾఆ͢Δ
  7. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } placeablesͷαΠζΛΈͯ਌ͷαΠζΛܭࢉ͢Δ
  8. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } placeablesΛplace͍ͯ͘͠
  9. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } placeablesΛplace͍ͯ͘͠
  10. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } placeablesΛplace͍ͯ͘͠
  11. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } ഑ஔͨ͠placeableͷwidth෼͚ͩoffsetʹՃࢉ͍ͯ͘͠
  12. val placeables = measurables.map { measurable -> measurable.measure(constraints.copy(minWidth = 0,

    minHeight = 0)) } val parentWidth = placeables.sumOf { it.width } .coerceAtMost(constraints.maxWidth) val parentHeight = placeables.maxOf { it.height } .coerceAtMost(constraints.maxHeight) return layout(parentWidth, parentHeight) { var offsetX = 0 for (placeable in placeables) { placeable.place(offsetX, 0) offsetX += placeable.width if (offsetX > parentWidth) break } } ਌ͷ֎ʹग़ͨΒplaceऴྃ
  13. class OverlapRowMeasurePolicy(private val overlapWidth: Dp) : MeasurePolicy { override fun

    MeasureScope.measure(measurables: List<Measurable>, constraints: Constraints): MeasureResult { val childConstraint = constraints.copy(minWidth = 0, minHeight = 0) val placeables = measurables.map { measurable -> measurable.measure(childConstraint) } val width = placeables.sumOf { it.width }.coerceAtMost(constraints.maxWidth) val height = placeables.maxOf { it.height }.coerceAtMost(constraints.maxHeight) return layout(width, height) { var offsetX = 0 for (placeable in placeables) { placeable.placeRelative(offsetX, 0) offsetX += (placeable.width - overlapWidth.toPx().toInt()) if (offsetX > width) break } } } } Overlap (࢖͍ಓ͋Γͦ͏!)
  14. class CircleMeasurePolicy : MeasurePolicy { override fun MeasureScope.measure(measurables: List<Measurable>, constraints:

    Constraints): MeasureResult { val childConstraint = constraints.copy(minWidth = 0, minHeight = 0) val placeables = measurables.map { measurable -> measurable.measure(childConstraint) } val maxChildWidth = placeables.maxOf { it.width } return layout(constraints.maxWidth, constraints.maxHeight) { val radian = Math.toRadians(90.0 / placeables.lastIndex) val radius = constraints.maxWidth - maxChildWidth for (i in placeables.indices) { val x = (cos(radian * i) * radius).toInt() val y = (sin(radian * i) * radius).toInt() placeables[i].placeRelative(x, y) } } } } Circle (Ұੜ࢖Θͳͦ͏)