Captain Allergy
Captain Allergy

Reputation: 86

Animate transition between column and row while scrolling in Jetpack Compose

When I scroll in a list, I want the composable sticky header to shrink. During that shrinking, the layout should by animated by the scrolling state to switch from a column layout, to a row layout.

Is there any way to achieve this in Jetpack Compose?

It should look like this: enter image description here

Upvotes: 2

Views: 2704

Answers (1)

weazy executee.
weazy executee.

Reputation: 86

You can try use MotionLayout – it's like Constraint Layout but much better:

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1" 

Firstly create a motion scene in json5 format. For your situation it will be something like this:

{
  ConstraintSets: {
    start: {
      value: {
        start: [ 'parent', 'start' ],
        top: [ 'parent', 'top' ],
      },
      title: {
        start: [ 'parent', 'start' ],
        top: [ 'value', 'bottom' ],
      }
    },
    end: {
      value: {
        top: [ 'parent', 'top' ],
        start: [ 'title', 'end' ],
      },
      title: {
        start: [ 'parent', 'start' ],
        top: [ 'parent', 'top' ],
      }
    }
  }
}

MotionLayout gets 3 required parameters: motionScene (string with json5 above), content (your composable) and progress value (float from 0 to 1).

  1. Create scroll state and progress calculation:

    val scrollState = rememberScrollState() val progress = (scrollState.value.toFloat() / 100).takeIf { it <= 1 } ?: 1f

  2. Create MotionLayout:

     MotionLayout(
         motionScene = MotionScene(<json5 string>),
         progress = progress
     ) {
         Text(modifier = Modifier.layoutId("value"), text = "Value")
         Text(modifier = Modifier.layoutId("title"), text = "Title")
     }
    
  3. Connect the scrollState to your scrollable content:

     Column(modifier = Modifier.verticalScroll(scrollState)) {
         repeat(20) {
             Text(
                 modifier = Modifier
                     .fillMaxWidth()
                     .padding(16.dp),
                 text = it.toString()
             )
         }
     }
    

the result of scrolling

Upvotes: 7

Related Questions