Anyone here using movableContentOf() API ? (<https...
# compose
a
Anyone here using movableContentOf() API ? (https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/runtime/design/movable-content.md) for which usecase? Thanks šŸ™‚
s
I tried using it for this case: There’s a Login page, which has two buttons at the bottom of the screen. When the first step is done, the next state of the screen only has 1 button, which happens to look like the top button. Button #1 is Filled, button #2 is outlined, therefore I thought it’d be cool for #1 to ā€œslideā€ down slowly. Visuals:
Copy code
+-----------+       +-----------+
|           |       |           |
|           |       |           |
|           |       |           |
| +-------+ |       |           |
| |   1   | |       |           |
| +-------+ |  -->  |           |   
| +-------+ |       | +-------+ |
| |   2   | |       | |   1   | |
| +-------+ |       | +-------+ |
+-----------+       +-----------+
Now it cross-fades between these two states, but I wanted the button ā€œ1" to fluidly move from the top position to the bottom position. So moved that item into a movableContent, slapped this modifier on it
Copy code
fun Modifier.animatePlacementInWindow(): Modifier = composed {
  val coroutineScope = rememberCoroutineScope()
  var targetOffset by remember { mutableStateOf(IntOffset.Zero) }
  var animatable by remember {
    mutableStateOf<Animatable<IntOffset, AnimationVector2D>?>(null)
  }
  this
    .onPlaced {
      targetOffset = it.positionInWindow().round()
    }
    .offset {
      val anim = animatable ?: Animatable(targetOffset, IntOffset.VectorConverter).also { animatable = it }
      if (anim.targetValue != targetOffset) {
        coroutineScope.launch {
          anim.animateTo(targetOffset, spring(stiffness = Spring.StiffnessVeryLow))
        }
      }
      animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
    }
}
with hopes that it’d fluidly move to the next position. It worked, kinda, but I got stopped from this and the fact that having the movableContent going in and out of a SubCompose layout doesn’t work that well. And no, this didn’t fix it either, this was the first time I tried to use it and couldn’t, then saw on the release notes that it should be fixed with this CL and tried again but alas, it didn’t work that time either šŸ˜„ You can tell I was really finding an excuse to play with the movableContentOf() API but unfortunately didn’t get to ship it yet. Note: These two states are pure compose state on one destination, not using navigation library for these two states, so I can do this myself without relying on waiting for navigation to support some shape of a ā€œshared element transitionā€ which would otherwise hopefully make this possible.
a
Gotcha, thanks for sharing!
c
I tried using movable as a means for child composables to send a composable to render to some other part of the composable tree. In my case it was to a parent two levels above which was its contents to render the value of a bottomsheet. Almost got it working but had to move away since design had changed