0

We have been working on an android project, and we faced with a problem in animation into the motionLayout when recyclerView is scrolling (you can see in video).

after scroll in anywhere on screen animation is fine but after scroll recyclerview appBar animation is run but so weird.

I added picture and video from UI architect to avoid confusion.

enter image description here

ProfileFragment.kt

    private fun coordinateMotion() {
        val appBarLayout: AppBarLayout? = binding.appbarLayout
        val motionLayout: MotionLayout = binding.profileHeaderInfo as MotionLayout

        val p = DecimalFormat("0.0");

        val listener = AppBarLayout.OnOffsetChangedListener { unused, verticalOffset ->
            val seekPosition = -verticalOffset / appBarLayout?.totalScrollRange!!.toFloat()
            motionLayout.progress = seekPosition
            Log.d(TAG, "coordinateMotion: $seekPosition")
        }

        appBarLayout?.addOnOffsetChangedListener(listener)
    }

ProfileFragment:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:fillViewport="true"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <include
                android:id="@+id/profile_include"
                layout="@layout/profile_layout_content" />
        </androidx.core.widget.NestedScrollView>

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <androidx.constraintlayout.motion.widget.MotionLayout
                android:id="@+id/profile_header_info"
                android:layout_width="match_parent"
                app:motionDebug="SHOW_PATH"
                android:layout_height="wrap_content"
                android:minHeight="80dp"
                android:background="@color/primary"
                app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"
                app:layoutDescription="@xml/fragment_profile_xml_profile_header_info_scene"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                .....

            </androidx.constraintlayout.motion.widget.MotionLayout>
        </com.google.android.material.appbar.AppBarLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

app ui architect

fragment_profile_xml_profile_header_info_scene

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/profile_user_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="24dp"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toEndOf="@+id/profile_image"
            motion:layout_constraintTop_toTopOf="@+id/profile_image">
        </Constraint>
        <Constraint
            android:id="@+id/profile_user_login"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            motion:layout_constraintBottom_toTopOf="@+id/profile_user_desc"
            motion:layout_constraintEnd_toEndOf="@+id/profile_user_name"
            motion:layout_constraintStart_toStartOf="@+id/profile_user_name"
            motion:layout_constraintTop_toBottomOf="@+id/profile_user_name">
        </Constraint>
        <Constraint
            android:id="@+id/profile_user_desc"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            motion:layout_constraintBottom_toBottomOf="@+id/profile_image"
            motion:layout_constraintEnd_toEndOf="@+id/profile_user_login"
            motion:layout_constraintStart_toStartOf="@+id/profile_user_login"
            motion:layout_constraintTop_toBottomOf="@+id/profile_user_login" />
        <Constraint
            android:id="@+id/profile_image"
            android:layout_width="75dp"
            android:layout_height="75dp"
            android:layout_marginStart="24dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="16dp"
            android:elevation="10dp"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.0"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/profile_user_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            motion:layout_constraintStart_toEndOf="@+id/profile_image"
            motion:layout_constraintTop_toTopOf="@+id/profile_image">
            <CustomAttribute
                motion:attributeName="textSize"
                motion:customDimension="10sp" />
        </Constraint>
        <Constraint
            android:id="@+id/profile_user_login"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            motion:layout_constraintBottom_toBottomOf="@id/profile_user_name"
            motion:layout_constraintStart_toEndOf="@+id/profile_user_name"
            motion:layout_constraintTop_toTopOf="@id/profile_user_name"
            motion:layout_constraintEnd_toEndOf="parent">

            <CustomAttribute
                motion:attributeName="textSize"
                motion:customDimension="8sp" />
        </Constraint>
        <Constraint
            android:id="@+id/profile_user_desc"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            motion:layout_constraintBottom_toBottomOf="@+id/profile_image"
            motion:layout_constraintEnd_toEndOf="@+id/profile_user_login"
            motion:layout_constraintStart_toStartOf="@+id/profile_user_name"
            motion:layout_constraintTop_toBottomOf="@+id/profile_user_name" />
        <Constraint
            android:id="@+id/profile_image"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginStart="24dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="16dp"
            android:elevation="10dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintHorizontal_bias="0.0"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/profile_header_divider"
            android:layout_width="0dp"
            android:layout_height="1dp"
            android:layout_marginTop="0dp"
            motion:layout_constraintEnd_toEndOf="@+id/profile_user_desc"
            motion:layout_constraintStart_toStartOf="@+id/profile_image"
            motion:layout_constraintTop_toBottomOf="@+id/profile_user_desc" />
        <Constraint
            android:id="@+id/profile_header_company_icon"
            android:layout_width="20dp"
            android:layout_height="20dp"
            motion:layout_constraintStart_toStartOf="@+id/profile_header_divider"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
        <KeyFrameSet>
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_divider" />
        </KeyFrameSet>
        <KeyFrameSet>
<!--            <KeyAttribute-->
<!--                android:alpha="0"-->
<!--                motion:framePosition="100"-->
<!--                motion:motionTarget="@+id/profile_user_desc" />-->
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_company" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_location" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_create_at" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_company_icon" />
            <KeyAttribute
                android:alpha="0.0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_location_icon" />
            <KeyAttribute
                android:alpha="0"
                motion:framePosition="100"
                motion:motionTarget="@+id/profile_header_create_at_icon" />
        </KeyFrameSet>

        <OnSwipe />

    </Transition>
</MotionScene>
Milad Targholi
  • 102
  • 1
  • 8

1 Answers1

0

You should determine two transition one startToEnd one endToStart after that add keyAttribute for things that is alpha zero like this

<KeyAttribute
                android:alpha="0"
                motion:framePosition="20"
                motion:motionTarget="@+id/profile_header_company_icon" />

When you use framePosition="100" your company icon gone at the end of motionlayout animation and this part of bad transition take place. You can play with frame position on both start and end transition.

sajadab
  • 383
  • 2
  • 11