Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KeyAttribute in MotionLayout is ignored on view "visibility" change

I'm using MotionLayout and <MotionScene /> to animate a bottomSheet View content, following swipe animation.

Between start and end scenes I'd like to make appear a view view_player_status_margin using visibility from gone to visible (not using alpha because an other view is link by constraint to the one I want to make appears).

It's ok using standard <Constraint /> in <ConstraintSet />, but when I link visibility to a <KeyAttribute /> to make the view appears only on last frames of the animation it doesn't doesn't follow the frame specific rule position.

My usage of <KeyAttribute /> seems correct because it works on alpha for the two others views.

Is there specific restrictions using KeyAttribute with visibilityattribute ?

<?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">

    <Transition
        app:constraintSetEnd="@+id/player_scene_set_expanded"
        app:constraintSetStart="@+id/player_scene_set_collapsed"
        app:motionInterpolator="easeIn">

        <KeyFrameSet>

            <KeyAttribute
                android:visibility="gone"
                app:framePosition="80"
                app:motionTarget="@id/view_player_status_margin" />

            <KeyAttribute
                android:alpha="0"
                app:framePosition="20"
                app:motionTarget="@id/view_player_collapsed" />

            <KeyAttribute
                android:alpha="1"
                app:framePosition="20"
                app:motionTarget="@id/view_player_expanded" />

        </KeyFrameSet>

    </Transition>

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

        <Constraint
            android:id="@+id/view_player_collapsed"
            android:layout_width="0dp"
            android:layout_height="64dp"
            android:alpha="1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <Constraint
            android:id="@+id/view_player_expanded"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:alpha="0"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/view_player_status_margin"/>

        <Constraint
            android:id="@+id/view_player_status_margin"
            android:layout_width="0dp"
            android:layout_height="38dp"
            android:visibility="gone"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

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

        <Constraint
            android:id="@+id/view_player_collapsed"
            android:layout_width="0dp"
            android:layout_height="64dp"
            android:alpha="0"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <Constraint
            android:id="@+id/view_player_expanded"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:alpha="1"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/view_player_status_line" />

        <Constraint
            android:id="@+id/view_player_status_line"
            android:layout_width="0dp"
            android:layout_height="38dp"
            android:visibility="visible"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

</MotionScene>
like image 706
smora Avatar asked Mar 15 '20 14:03

smora


1 Answers

I wanted to do something like this, and as a beginner it's a bit confusing to me, but I thought to share what I could do so far.

For me, I couldn't find an KeyAttribute for visibility, so I had to make use of CustomAttribute:

<KeyAttribute
   motion:framePosition="0"
   motion:motionTarget="@id/background">
   <CustomAttribute
       motion:attributeName="visibility"
       motion:customIntegerValue="8" />
</KeyAttribute>

And following are the corresponding integer values for visibility are:

Visible = 0
Invisible = 4
Gone = 8

So, for my need, I had a background view, and I wanted motion to animate its alpha from 0 to 1. The background view should be gone when alpha is 0, and once alpha is getting greater than 0 just stay visible all the time, but I don't want any animation for visibility at all.
Configuring a KeyFrameSet was not enough for me, I had to tell motion to ignore animating visibility of the background view.

Of course, I had to set visibility of the background view for @id/start and @id/end constraint sets, following is the MotionScene demonstrating all of this:

<MotionScene
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">


    <Transition
        android:id="@+id/transition"
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="@integer/standard_duration">

       <KeyFrameSet>
           <KeyAttribute
               motion:framePosition="0"
               motion:motionTarget="@id/background">
               <CustomAttribute
                   motion:attributeName="visibility"
                   motion:customIntegerValue="8" />
           </KeyAttribute>

           <KeyAttribute
               motion:framePosition="1"
               motion:motionTarget="@id/background">
               <CustomAttribute
                   motion:attributeName="visibility"
                   motion:customIntegerValue="0" />
           </KeyAttribute>
       </KeyFrameSet>

    </Transition>

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

        <Constraint
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:alpha="0.5"
            android:visibility="gone"
            motion:visibilityMode="ignore"
        />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        ...

        <Constraint
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:alpha="0.5"
            android:visibility="visible"
            motion:visibilityMode="ignore"
        />
    </ConstraintSet>

</MotionScene>
like image 169
Ahmed Shendy Avatar answered Sep 29 '22 14:09

Ahmed Shendy