Search code examples
androidandroid-motionlayout

How to scroll a sync'd up MotionLayout+AppBarLayout programmatically?


Consider the following Coordinator+AppBar+MotionLayout and its MotionScene from Google's demo. This creates a MotionLayout that sync's its Transition progress when the user is scrolling.

Video Preview: https://i.imgur.com/1MnPB8R.mp4

However, I would like to do this in programmatically in Kotlin. Here are my failed attempts.

val motion = findViewById<MotionLayout>(R.id.constraintToolbar)
motion.transitionToState(R.id.end)

The above would cause the MotionLayout to animate, but would immediately blink back to the start state once finished. The AppBarLayout also does not change height.

val appbar = findViewById<AppBarLayout>(R.id.app_bar)
val scrollable = findViewById<NestedScrollView>(R.id.scrollable)
val s = if(motion.progress==0F) appbar.totalScrollRange else 0
scrollable.smoothScrollTo(0, s)

The above scrolls the NestedScrollView, but the AppBarLayout and MotionLayout does not receive the scroll events.

val s = if(motion.progress==0F)-appbar.totalScrollRange else 0
val appbar = findViewById<AppBarLayout>(R.id.app_bar)
appbar.scrollTo(0,s)
appbar.offsetTopAndBottom(s)

The above shifts the AppBarLayout, breaking the layout completely.

How do you trigger this scroll programmatically?


Solution

  • If there's only 2 states, you should try setExpanded()

    val e = motion.progress != 0F
    appbar.setExpanded(e, true)