Duplicate Id in Constraint Sets - android

I am trying to implement a simple animation through motionLayout, the aim is to click to move an image, but the constraint sets arent allowing duplicate ids
<ConstraintSet android:id="#+id/starting_set">
<Constraint
android:id="#+id/tracker"
app:layout_constraintBottom_toBottomOf="#+id/t1"
tools:layout_editor_absoluteX="167dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
/>
</ConstraintSet>
there is an error on the ending constraint, on constraint id (tracker) of duplicacy

for most of drag animation you don't need to to have duplicates at all. Eg sample to move view horizontally after click and drag
<MotionScene
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="#layout/motion_01_cl_start"
motion:constraintSetEnd="#layout/motion_01_cl_end"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="#+id/button"
motion:touchAnchorSide="right"
motion:dragDirection="dragRight" />
</Transition>
</MotionScene>
you can fin more samples here
https://github.com/googlesamples/android-ConstraintLayoutExamples
also if you have several Constraint make sure they have Constraint name and they are in different sets. Sample below will not work and will complain about duplicates. If you cange Button to Constraint than it will work.
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="1000"
motion:motionInterpolator="linear">
<OnSwipe
motion:dragDirection="dragRight"
motion:touchAnchorId="#id/button"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Button
android:id="#id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="BackgroundColor"
motion:customColorValue="#D81B60" />
</Button>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Button
android:id="#id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="BackgroundColor"
motion:customColorValue="#9999FF" />
</Button>
</ConstraintSet>

#Yarh Answer is correct. Here is the short version for my case: I accidently just copied the code from the layout-xml into the scene file. But I forgot to change the xml tag to Constraint. Doing so removed the error about DuplicateIds.

Related

Android Flip and shuffle animation using motion layout

I want to create an animation like . I am able to achieve the card flip animation and its smooth as expected, but I am not able to get this shuffle animation to work, like after the cards are flipped they are collected at one point and then distributed again. Despite of several attempts i am not able to get a smooth animation. My animation path becomes something like this.
This is my motion scene file.
<?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">
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="5000"
>
<OnSwipe
motion:dragDirection="dragRight"
motion:touchAnchorId="#+id/button"
motion:touchAnchorSide="right" />
<KeyFrameSet>
<KeyPosition
motion:framePosition="50"
motion:keyPositionType="parentRelative"
motion:motionTarget="#+id/button"
motion:percentY="1" />
<KeyPosition
motion:framePosition="70"
motion:keyPositionType="parentRelative"
motion:motionTarget="#+id/button"
motion:pathMotionArc="flip"
motion:curveFit="spline"
motion:percentX="-0.1"
motion:percentY="0.8" />
<KeyPosition
motion:framePosition="80"
motion:keyPositionType="parentRelative"
motion:motionTarget="#+id/button"
motion:percentX="0.7"
motion:percentY="0.7" />
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#D81B60" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#9999FF" />
</Constraint>
</ConstraintSet>
</MotionScene>

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

How to create multiple transitions on a single view

Is it possible to implement draggable panel!
using motion layout?
I have tried to play around the google sample of youtube like transition by using multiple Transitions with OnSwipe on a single view but not able to succeed. Can anyone please guide me to implement how to apply the two transitions using OnSwipe on the same view?
<?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/expanded"
app:constraintSetStart="#id/collapsed"
app:duration="100"
app:interpolator="easeInOut">
<OnSwipe
app:dragDirection="dragUp"
app:maxAcceleration="200"
app:touchAnchorId="#+id/videoViewContainer"
app:touchAnchorSide="top" />
<KeyFrameSet>
<!--<KeyAttribute-->
<!--app:framePosition="0"-->
<!--app:target="#id/videoView">-->
<!--<CustomAttribute-->
<!--app:attributeName="EndPadding"-->
<!--app:customDimension="#dimen/video_view_right_padding" />-->
<!--</KeyAttribute>-->
<!--<KeyAttribute-->
<!--app:framePosition="20"-->
<!--app:target="#id/videoView">-->
<!--<CustomAttribute-->
<!--app:attributeName="EndPadding"-->
<!--app:customDimension="0dp" />-->
<!--</KeyAttribute>-->
<KeyAttribute
app:framePosition="0"
app:target="#id/videoMotionLayout">
<CustomAttribute
app:attributeName="height"
app:customDimension="90dp" />
</KeyAttribute>
<KeyAttribute
app:framePosition="20"
app:target="#id/videoMotionLayout">
<CustomAttribute
app:attributeName="height"
app:customDimension="250dp" />
</KeyAttribute>
<KeyAttribute
app:framePosition="0"
app:target="#id/videoMotionLayout">
<CustomAttribute
app:attributeName="width"
app:customDimension="160dp" />
</KeyAttribute>
<KeyAttribute
app:framePosition="20"
app:target="#id/videoMotionLayout">
<CustomAttribute
app:attributeName="width"
app:customDimension="0dp" />
</KeyAttribute>
<KeyAttribute
android:alpha="0"
app:framePosition="0"
app:target="#id/videoRecyclerView" />
<KeyAttribute
android:alpha="1"
app:framePosition="100"
app:target="#id/videoRecyclerView" />
<KeyAttribute
app:framePosition="0"
app:target="#id/videoViewContainer">
<CustomAttribute
app:attributeName="cardElevation"
app:customDimension="5dp" />
</KeyAttribute>
<KeyAttribute
app:framePosition="3"
app:target="#id/videoViewContainer">
<CustomAttribute
app:attributeName="cardElevation"
app:customDimension="0dp" />
</KeyAttribute>
</KeyFrameSet>
</Transition>
<Transition
app:constraintSetEnd="#id/close"
app:constraintSetStart="#id/close"
app:duration="100"
app:interpolator="easeInOut">
<OnSwipe
app:dragDirection="dragLeft"
app:maxAcceleration="200"
app:touchAnchorId="#+id/videoViewContainer"
app:touchAnchorSide="top" />
<KeyFrameSet>
<KeyAttribute
app:framePosition="0"
app:target="#id/videoMotionLayout">
</KeyAttribute>
</KeyFrameSet>
</Transition>
<Transition
app:constraintSetEnd="#id/close"
app:constraintSetStart="#id/close"
app:duration="100"
app:interpolator="easeInOut">
<OnSwipe
app:dragDirection="dragRight"
app:maxAcceleration="200"
app:touchAnchorId="#+id/videoViewContainer"
app:touchAnchorSide="top" />
<KeyFrameSet>
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/close">
<Constraint
android:id="#id/videoViewContainer"
android:layout_height="250dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoViewContainer" />
</ConstraintSet>
<ConstraintSet android:id="#+id/collapsed">
<Constraint
android:id="#id/videoViewContainer"
android:layout_height="113dp"
android:layout_width="200dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="65dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Constraint
android:id="#id/content"
android:layout_width="match_parent"
android:layout_height="-1dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="66dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/videoViewContainer" />
</ConstraintSet>
</MotionScene>
It would be helpful If I can move the mini-player scene to the left and right directions as well. Thank you.
How to create multiple transitions on a single view
It is possible to add multiple transitions to the same View. For example we can define animations with motion:dragDirection="dragDown" and motion:dragDirection="dragUp" on the same touchAnchorId without any problem. The possible configurations are given below,
motion:dragDirection="dragUp"
motion:dragDirection="dragDown"
motion:dragDirection="dragLeft"
motion:dragDirection="dragRight"
What to do
So, here I show you how to implement all these together on the same View.
Before writing any code, please see the below gif to better understand what we are trying to create.
How to do
Add the ConstraintLayout dependency:
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
}
Create a MotionLayout file:
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:motion="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/motionLayout"
motion:layoutDescription="#xml/motionscene1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="240dp"
android:background="#453672"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
Create a MotionScene:
A MotionScene is an XML resource file that contains all of the motion descriptions for the corresponding layout. Put the file under res/xml/ folder
motionscene1.xml
<?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">
<!-- top to bottom right-->
<Transition
motion:constraintSetEnd="#id/step2"
motion:constraintSetStart="#id/step1"
motion:duration="500">
<OnSwipe
motion:dragDirection="dragDown"
motion:touchAnchorId="#id/image"
motion:touchAnchorSide="top" />
</Transition>
<!-- bottom right to bottom left-->
<Transition
motion:constraintSetEnd="#id/step3"
motion:constraintSetStart="#id/step2"
motion:duration="500">
<OnSwipe
motion:dragDirection="dragLeft"
motion:touchAnchorId="#id/image"
motion:touchAnchorSide="left" />
</Transition>
<!-- bottom left to top-->
<Transition
motion:constraintSetEnd="#id/step1"
motion:constraintSetStart="#id/step3"
motion:duration="500">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="#id/image"
motion:touchAnchorSide="top" />
</Transition>
<!-- bottom right to top-->
<Transition
motion:constraintSetEnd="#id/step1"
motion:constraintSetStart="#id/step2"
motion:duration="500">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="#id/image"
motion:touchAnchorSide="top" />
</Transition>
<!-- place the view on top-->
<ConstraintSet android:id="#+id/step1">
<Constraint
android:id="#id/image"
android:layout_width="match_parent"
android:layout_height="240dp"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<PropertySet android:alpha="1" />
</Constraint>
</ConstraintSet>
<!-- place the view on bottom right-->
<ConstraintSet android:id="#+id/step2">
<Constraint
android:id="#id/image"
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent">
<PropertySet android:alpha="1" />
</Constraint>
</ConstraintSet>
<!-- place the view on bottom left-->
<ConstraintSet android:id="#+id/step3">
<Constraint
android:id="#id/image"
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent">
<PropertySet android:alpha="1" />
</Constraint>
</ConstraintSet>
</MotionScene>
That's all. You created an amazing custom animation with out writing any java/kotlin code. MotionLayout is fully declarative, meaning that you can describe any transitions in XML, no matter how complex.

MotionLayout in android doesn't work with multiple OnClick transitions

I'm having an issue with the MotionLayout.
I have created a scene and it works when I'm using one onClick transition. But I need to have two.
What I want to do is: When clicking on a button in view one this view will hide and another view will show. This works.
But now when I click a button in the other view, I want to show the first view and the second needs to hide.
This sort of works, only problem is that it doesn't do it with a transition. It just shows.
My scene looks like:
<?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">
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="2000"
motion:motionInterpolator="easeOut">
<OnClick
motion:clickAction="transitionToEnd"
motion:targetId="#+id/hide_menu" />
</Transition>
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="2000"
motion:motionInterpolator="easeInOut">
<OnClick
motion:clickAction="transitionToStart"
motion:targetId="#+id/quick_menu_show_menu" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/sidebar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:translationX="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/quick_menu"
android:layout_width="19dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:translationX="-70dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/sidebar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:translationX="-70dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/quick_menu"
android:layout_width="19dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:translationX="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
hope anyone can help.
Kind regards,
JKorsten
For some reason this solves the issue, but I hope someone can explain why this is.
<Transition
motion:constraintSetEnd="#+id/start"
motion:constraintSetStart="#+id/end"
motion:duration="2000"
motion:motionInterpolator="easeIn">
<OnClick
motion:clickAction="transitionToStart"
motion:targetId="#+id/quick_menu_show_menu" />
</Transition>
As I read it: it does a easeIn from ConstraintSetEnd to ConstraintSetStart (transitionToStart), but I needed to change ConstraintSetEnd to #+id/start and ConstraintSetStart to #+id/end.
You have to add another transition set I guess
Your first transition set should be like this
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="2000"
motion:motionInterpolator="easeIn">
<OnClick
motion:clickAction="transitionToEnd"
motion:targetId="#+id/quick_menu_show_menu" />
</Transition>
and below that add another transition set like this
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="2000"
motion:motionInterpolator="easeIn">
<OnClick
motion:clickAction="transitionToStart"
motion:targetId="#+id/(your another view ID)" />
</Transition>
Hope that works

Fade in, fade out not working in MotionLayout

I'm trying to make an effect of fade in, fade out using alpha and motionLayout, but it seems that it's not working.
This is the imageView that I want to fade.
<ImageView
android:id="#+id/tijeras"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:contentDescription="#string/tijeras"
android:src="#drawable/ic_tijeras" />
</android.support.constraint.motion.MotionLayout>
And this is the motion file
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<Transition
app:duration="2000"
app:constraintSetStart="#+id/start"
app:constraintSetEnd="#+id/end">
<KeyFrameSet>
<KeyAttribute
app:framePosition="0"
app:motionTarget="#id/tijeras"
android:alpha="1.0"/>
<KeyAttribute
app:framePosition="50"
app:motionTarget="#id/tijeras"
android:alpha="0.0"/>
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint android:id="#+id/tijeras"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo"/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#+id/tijeras"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo"/>
</ConstraintSet>
</MotionScene>
I can see the image, but it's not doing the alpha in and out. Any idea? Do I need to trigger it for starting?
It looks like you have set the alpha as 1.0 android:alpha="1.0" on both the start and end ConstraintSet.
You can more easily set the alpha to update with a CustomAttribute by removing alpha from the KeyAttribute and placing the following below your Transition element
<ConstraintSet android:id="#+id/start">
<Constraint android:id="#+id/tijeras"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo">
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="0.0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#+id/tijeras"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="1.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo">
<CustomAttribute
motion:attributeName="alpha"
motion:customFloatValue="1.0" />
</Constraint>
</ConstraintSet>
I think that i have found the problem and the solution. So you are defining two ConstraintSet (start, end) and in both alpha = 1, it means that your view is visible in both of them right ? Now let's see your KeyFrameSet
<KeyFrameSet>
<KeyAttribute
app:framePosition="0"
app:motionTarget="#id/tijeras"
android:alpha="1.0"/>
<KeyAttribute
app:framePosition="50"
app:motionTarget="#id/tijeras"
android:alpha="0.0"/>
</KeyFrameSet>
You're saying that at framePosition = 0 your view is visible (alpha=1), then in the middle of your transition (framePosition = 50 ) you are hiding your view (alpha=0). It means that when you are at framePosition = 100 (end of your transition) the alpha will be 1 again because in your ConstraintSet (end) is equal to 1.
So try to change it like this, instead of 50, framePosition = 100
<KeyFrameSet>
<KeyAttribute
app:framePosition="0"
app:motionTarget="#id/tijeras"
android:alpha="1.0"/>
<KeyAttribute
app:framePosition="100"
app:motionTarget="#id/tijeras"
android:alpha="0.0"/>
</KeyFrameSet>
There is no need setting a CustomAttribute, this solution should work:
BaseView
<!-- Other views -->
<ImageView
android:id="#+id/tijeras"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:contentDescription="#string/tijeras"
android:src="#drawable/ic_tijeras" />
Content Scene
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<Transition
app:duration="2000"
app:constraintSetStart="#+id/start"
app:constraintSetEnd="#+id/end">
<KeyFrameSet>
<KeyAttribute
app:framePosition="50"
app:motionTarget="#id/tijeras"
android:alpha="0.0"/> <!-- Set alpha to zero -->
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/start">
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#id/tijeras" <!-- without + -->
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.0" <!-- set alpha to zero -->
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/logo"/>
</ConstraintSet>
</MotionScene>

Categories

Resources