View inside MotionLayout not retaining the elevation change

Viewed 1391

I was trying to achieve animations we do in coordinator layout like collapsing toolbar using motion layout. I have the following motion layout with a toolbar(framelayout), imageview and a scrollview. The elevation of toolbar is increased with swipe of scrollview. But after scrollview moves under toolbar, its elevation(shadow) is no longer visible. I am not sure why is the shadow not visible.

 <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/activity_main_scene"
    app:showPaths="true"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/iv_top"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/top"
        android:scaleType="centerCrop"
        android:src="@drawable/test_vector"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar" />

    <androidx.core.widget.NestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_top">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:text="@string/stub"
            android:textSize="24sp" />

    </androidx.core.widget.NestedScrollView>

    <FrameLayout
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:background="@color/colorPrimary"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>

My motionscene is:

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

    <ConstraintSet android:id="@+id/start">
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/iv_top"
            android:layout_height="0dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@id/toolbar"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:elevation="20dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>

    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start"
        app:duration="1000">
        <OnSwipe
            app:touchAnchorId="@+id/scroll_view"
            app:touchAnchorSide="top" />
    </Transition>
</MotionScene>

enter image description here

enter image description here

enter image description here

1 Answers

You put the shadow on the toolbar but i think what you really want is to put it on the ImageView that moves up and down.

The problem is that the ImageView doesn't have a background but just a src. So you need to define where to put the shadow by adding android:outlineProvider="bounds". Now a bit of the shadow is visible above the image too, so you have to raise the toolbar even higher and remove it's own shadow with android:outlineProvider="none". All those changes are in the activty_main.xml.

The activity_main_scene.xml becomes much smaller now. Just make sure to keep the android:layout_height at least 1dp because otherwise the shadow disappears with the view.

This is the code i used:

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.motion.widget.MotionLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/activity_main_scene"
    app:showPaths="true"
    tools:context=".MainActivity">
    
    <FrameLayout
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="60dp"
        android:background="@color/red4"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:elevation="21dp"
        android:outlineProvider="none"/>

    <ImageView
        android:id="@+id/iv_top"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="string/top"
        android:scaleType="centerCrop"
        android:src="@drawable/sof"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar"
        android:elevation="20dp"
        android:outlineProvider="bounds"/>
    
    <androidx.core.widget.NestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/iv_top">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:text="string/stub"
            android:textSize="24sp" />

    </androidx.core.widget.NestedScrollView>

</androidx.constraintlayout.motion.widget.MotionLayout>

activity_main_scene.xml:

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ConstraintSet android:id="@+id/start">
    </ConstraintSet>
    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/iv_top"
            android:layout_height="1dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    </ConstraintSet>
    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start"
        app:duration="1000">
        <OnSwipe
            app:touchAnchorId="@+id/scroll_view"
            app:touchAnchorSide="top" />
    </Transition>
</MotionScene>
Related