I'm trying to add multiple animations in my MotionLayout
. The scene currently has two Transitions
but will eventually have four.
First transition is kind of a mix between YouTube Player and Netflix Player where controllers disappear either by dropping down or shrinking.
The second transition is a simple rotation applied on the rewindButton
.
Layout Hierarchy:
MotionLayout (First transition <OnClick>)
-> Previous Button.
-> Rewind Button. (Second transition <OnClick>)
-> Play/Plause Button.
-> Forward Button.
-> Next Button.
-> Other Views.
Layout for reference:
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="@+id/playerUIContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:elevation="3dp"
app:layoutDescription="@xml/player_controls_animations"
tools:background="#000000"
tools:visibility="visible"
>
<com.aaa.views.UntouchableCarouselView
android:id="@+id/screenshotsView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:clickable="false"
android:visibility="gone"
app:indicatorVisibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:slideInterval="10000"
tools:visibility="visible"
/>
<ImageView
android:id="@+id/backButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:padding="5dp"
android:contentDescription="@string/dummyImageDescription"
android:src="@drawable/ic_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:visibility="visible"
/>
<TextView
android:id="@+id/contentTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:textColor="#FFFFFF"
android:textSize="@dimen/player_content_title_text_size"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@id/backButton"
app:layout_constraintEnd_toStartOf="@id/channelListButton"
app:layout_constraintTop_toTopOf="@id/backButton"
app:layout_constraintBottom_toBottomOf="@id/backButton"
tools:text="Harry Potter and The Prisoner of Azkaban"
tools:visibility="visible"
/>
<ImageView
android:id="@+id/channelListButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:src="@drawable/menu"
android:padding="5dp"
android:contentDescription="@string/dummyImageDescription"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/backButton"
android:visibility="gone"
tools:visibility="gone"
/>
<ImageView
android:id="@+id/rewindButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_rewind_10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/prevButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
app:layout_constraintHorizontal_chainStyle="spread"
/>
<ImageView
android:id="@+id/prevButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/previous"
android:padding="5dp"
android:contentDescription="@string/dummyImageDescription"
app:layout_constraintStart_toEndOf="@id/rewindButton"
app:layout_constraintEnd_toStartOf="@+id/playPauseButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
app:layout_constraintHorizontal_chainStyle="spread"
android:visibility="gone"
tools:visibility="gone"
/>
<ImageView
android:id="@+id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_pause"
android:padding="5dp"
android:contentDescription="@string/dummyImageDescription"
app:layout_constraintStart_toEndOf="@id/prevButton"
app:layout_constraintEnd_toStartOf="@id/nextButton"
app:layout_constraintTop_toBottomOf="@id/contentTitle"
app:layout_constraintBottom_toTopOf="@id/timeSeekBar"
app:layout_constraintHorizontal_chainStyle="spread"
tools:visibility="visible"
/>
<ImageView
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/next"
android:padding="5dp"
android:contentDescription="@string/dummyImageDescription"
app:layout_constraintStart_toEndOf="@+id/playPauseButton"
app:layout_constraintEnd_toStartOf="@id/forwardButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
app:layout_constraintHorizontal_chainStyle="spread"
android:visibility="gone"
tools:visibility="gone"
/>
<ImageView
android:id="@+id/forwardButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_forward_10"
app:layout_constraintStart_toEndOf="@id/nextButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
app:layout_constraintHorizontal_chainStyle="spread"
/>
<ProgressBar
android:id="@+id/playerLoading"
style="?android:attr/progressBarStyleLarge"
android:layout_width="@dimen/player_loading_width"
android:layout_height="@dimen/player_loading_height"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/contentTitle"
app:layout_constraintBottom_toTopOf="@id/timeSeekBar"
tools:visibility="visible"
/>
<TextView
android:id="@+id/playerProgressUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textSize="@dimen/player_buffering_text_size"
android:textColor="@color/white"
app:layout_constraintLeft_toLeftOf="@id/playerLoading"
app:layout_constraintRight_toRightOf="@id/playerLoading"
app:layout_constraintTop_toBottomOf="@id/playerLoading"
tools:text="90%"
tools:visibility="visible"
/>
<TextView
android:id="@+id/seedsCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/player_torrent_info_text_size"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="@id/peersCount"
app:layout_constraintBottom_toTopOf="@id/peersCount"
android:visibility="visible"
android:alpha="1"
tools:text="50"
tools:visibility="visible"
/>
<TextView
android:id="@+id/peersCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/player_torrent_info_text_size"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="@id/playerDownloadSpeed"
app:layout_constraintBottom_toTopOf="@id/playerDownloadSpeed"
android:visibility="visible"
tools:text="3"
tools:visibility="visible"
/>
<TextView
android:id="@+id/playerDownloadSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/player_torrent_info_text_size"
android:textColor="@color/white"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="@id/totalDuration"
app:layout_constraintEnd_toEndOf="@id/totalDuration"
android:visibility="visible"
tools:text="123.45 KB/s"
tools:visibility="visible"
/>
<ImageView
android:id="@+id/subtitlesSwitchBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_subtitles_on"
android:background="@color/black"
app:layout_constraintStart_toStartOf="@id/currentPosition"
app:layout_constraintBottom_toTopOf="@id/currentPosition"
/>
<TextView
android:id="@+id/subtitlesText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="@dimen/player_subtitles_text_size"
android:paddingStart="@dimen/player_subtitles_text_padding_start"
android:paddingEnd="@dimen/player_subtitles_text_padding_end"
android:gravity="center"
android:background="@color/transparent_inversion_grey"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/playPauseButton"
app:layout_constraintBottom_toTopOf="@id/timeSeekBar"
app:layout_constraintStart_toEndOf="@id/subtitlesSwitchBtn"
app:layout_constraintEnd_toStartOf="@id/playerDownloadSpeed"
/>
<TextView
android:id="@+id/currentPosition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/player_ui_padding_start"
android:layout_marginBottom="@dimen/player_ui_padding_bottom"
android:gravity="center"
android:text="@string/default_time"
android:textSize="@dimen/player_current_time_text_size"
android:textColor="#FFFFFF"
android:singleLine="true"
android:ellipsize="none"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:text="@string/default_time"
tools:visibility="visible"
/>
<com.aaa.pieces_progressbar.PiecesSeekBar
android:id="@+id/timeSeekBar"
android:layout_width="0dp"
android:layout_height="@dimen/player_seek_bar_height"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:trackHeight="@dimen/player_seek_bar_track_height"
android:thumb="@drawable/player_seek_bar_thumb"
app:layout_constraintStart_toEndOf="@id/currentPosition"
app:layout_constraintEnd_toStartOf="@id/totalDuration"
app:layout_constraintTop_toTopOf="@+id/currentPosition"
app:layout_constraintBottom_toBottomOf="@id/currentPosition"
tools:visibility="visible"
/>
<TextView
android:id="@+id/totalDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/player_ui_padding_bottom"
android:layout_marginEnd="@dimen/player_ui_padding_end"
android:gravity="center"
android:text="@string/default_time"
android:textColor="#FFFFFF"
android:textSize="@dimen/player_current_time_text_size"
android:singleLine="true"
android:ellipsize="none"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/playerMaximizeButton"
tools:text="@string/default_time"
tools:visibility="visible"
/>
<ImageView
android:id="@+id/playerMaximizeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:visibility="visible"
android:src="@drawable/ic_fullscreen_enter"
android:layout_gravity="end"
android:contentDescription="@string/dummyImageDescription"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="gone"
/>
</androidx.constraintlayout.motion.widget.MotionLayout>
Scene Layout:
<MotionScene>
<Transition
motion:duration="1000"
motion:constraintSetStart="@id/rewindRotationOnClick"
motion:constraintSetEnd="@id/rewindRotationOnReset"
motion:motionInterpolator="easeInOut"
>
<OnClick
motion:targetId="@id/rewindButton"
motion:clickAction="transitionToEnd"
/>
<KeyFrameSet>
<KeyAttribute
motion:motionTarget="@id/rewindButton"
android:rotation="0"
motion:framePosition="1"
/>
<KeyAttribute
motion:motionTarget="@id/rewindButton"
android:rotation="90"
motion:framePosition="80"
/>
<KeyAttribute
motion:motionTarget="@id/rewindButton"
android:rotation="0"
motion:framePosition="99"
/>
</KeyFrameSet>
</Transition>
<ConstraintSet
android:id="@+id/rewindRotationOnClick"
>
<Constraint
android:id="@id/rewindButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/prevButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
/>
</ConstraintSet>
<ConstraintSet
android:id="@+id/rewindRotationOnReset"
>
<Constraint
android:id="@id/rewindButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/prevButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
/>
</ConstraintSet>
<Transition
motion:duration="@integer/player_controlsTransitionDuration"
motion:constraintSetStart="@id/showControls"
motion:constraintSetEnd="@id/hideControls"
motion:motionInterpolator="easeIn"
>
<OnClick
motion:clickAction="toggle"
motion:targetId="@id/playerUIContainer"
/>
</Transition>
<ConstraintSet
android:id="@+id/showControls"
>
<Constraint
android:id="@id/rewindButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/prevButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
/>
<Constraint
android:id="@id/playPauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintStart_toEndOf="@id/prevButton"
app:layout_constraintEnd_toStartOf="@id/nextButton"
app:layout_constraintTop_toBottomOf="@id/contentTitle"
app:layout_constraintBottom_toTopOf="@id/timeSeekBar"
/>
<Constraint
android:id="@id/forwardButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1"
app:layout_constraintStart_toEndOf="@id/playPauseButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
/>
<Constraint
android:id="@id/currentPosition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/player_ui_padding_start"
android:layout_marginBottom="@dimen/player_ui_padding_bottom"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<Constraint
android:id="@id/subtitlesSwitchBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/currentPosition"
app:layout_constraintBottom_toTopOf="@id/currentPosition"
/>
<Constraint
android:id="@id/timeSeekBar"
android:layout_width="0dp"
android:layout_height="@dimen/player_seek_bar_height"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="@id/currentPosition"
app:layout_constraintEnd_toStartOf="@id/totalDuration"
app:layout_constraintTop_toTopOf="@+id/currentPosition"
app:layout_constraintBottom_toBottomOf="@id/currentPosition"
/>
<Constraint
android:id="@id/seedsCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@id/peersCount"
app:layout_constraintBottom_toTopOf="@id/peersCount"
/>
<Constraint
android:id="@id/peersCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@id/playerDownloadSpeed"
app:layout_constraintBottom_toTopOf="@id/playerDownloadSpeed"
/>
<Constraint
android:id="@id/playerDownloadSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toTopOf="@id/totalDuration"
app:layout_constraintEnd_toEndOf="@id/totalDuration"
/>
<Constraint
android:id="@id/totalDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/player_ui_padding_bottom"
android:layout_marginEnd="@dimen/player_ui_padding_end"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/playerMaximizeButton"
/>
<Constraint
android:id="@id/contentTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
app:layout_constraintStart_toEndOf="@id/backButton"
app:layout_constraintEnd_toStartOf="@id/channelListButton"
app:layout_constraintTop_toTopOf="@id/backButton"
app:layout_constraintBottom_toBottomOf="@id/backButton"
/>
<Constraint
android:id="@id/backButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
</ConstraintSet>
<ConstraintSet
android:id="@+id/hideControls"
>
<Constraint
android:id="@id/rewindButton"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/prevButton"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
/>
<Constraint
android:id="@id/playPauseButton"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/contentTitle"
app:layout_constraintBottom_toTopOf="@id/timeSeekBar"
/>
<Constraint
android:id="@id/forwardButton"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
app:layout_constraintStart_toEndOf="@id/playPauseButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/playPauseButton"
app:layout_constraintBottom_toBottomOf="@id/playPauseButton"
/>
<Constraint
android:id="@id/currentPosition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/totalDuration"
/>
<Constraint
android:id="@id/subtitlesSwitchBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@id/currentPosition"
app:layout_constraintTop_toTopOf="@id/playerDownloadSpeed"
/>
<Constraint
android:id="@id/timeSeekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/currentPosition"
app:layout_constraintEnd_toStartOf="@id/totalDuration"
app:layout_constraintTop_toTopOf="@id/totalDuration"
/>
<Constraint
android:id="@id/seedsCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@id/peersCount"
app:layout_constraintTop_toBottomOf="parent"
/>
<Constraint
android:id="@id/peersCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@id/playerDownloadSpeed"
app:layout_constraintTop_toBottomOf="@id/seedsCount"
/>
<Constraint
android:id="@id/playerDownloadSpeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/peersCount"
app:layout_constraintEnd_toEndOf="@id/totalDuration"
/>
<Constraint
android:id="@id/totalDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/playerDownloadSpeed"
app:layout_constraintEnd_toStartOf="@id/playerMaximizeButton"
/>
<Constraint
android:id="@id/contentTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/backButton"
app:layout_constraintTop_toTopOf="@id/backButton"
app:layout_constraintBottom_toBottomOf="@id/backButton"
/>
<Constraint
android:id="@id/backButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
</ConstraintSet>
</MotionScene>
Start and end ConstraintSet
s are exactly the same for rewindButton
and the animation takes place in the <KeyFrameSet>. That is because I want the
rewindButton` to reset to its original state on completion.
Both these transitions work in the MotionLayout-Editor
, the problem is only the first transition works.
The second transition only works if I remove the first transition from the scene. But only on first click, I don't know why.
ConstraintLayout Version: 2.0.4.