How to create multiple transitions on a single view - android

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.

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>

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>

MotionLayout using Crossfade - altSrc appears on top of src (original image doesn't fade away)

I am using an ImageFilterView, in coordination with a MotionScene, to switch between Images on user swipe (I am also moving the image up).
The new image does appear, but the old image remains. I can see the altSrc image on top of the original image.
Am I doing something wrong? Is my expectation incorrect that, the old image will fade out?
Here is the relevant code:
layout.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:id="#+id/motionlayout_demo"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/the_scene_alt"
app:showPaths="true"
tools:context="com.designdemo.uaha.ui.MotionLayoutActivity">
...
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="#+id/nerd_text_img"
android:src="#drawable/ic_nerderytxt_old"
app:altSrc="#drawable/ic_nerderytxt_new"
android:layout_width="450dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.43"/>
...
</androidx.constraintlayout.motion.widget.MotionLayout>
the_scene_alt.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">
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="1000">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="#id/text_the"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/nerd_text_img"
android:layout_width="450dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintVertical_bias="0.43" >
<CustomAttribute
motion:attributeName="Crossfade"
motion:customFloatValue="0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/nerd_text_img"
android:layout_width="450dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintVertical_bias="0.33" >
<CustomAttribute
motion:attributeName="Crossfade"
motion:customFloatValue="1" />
</Constraint>
</ConstraintSet>
Use the flag:
app:overlay="false"

Failed linking file resources when using Motion Layout KeyPosition

I am getting
"Failed linking file resources"
with
"error: attribute type (aka com.testapp.client:type) not found"
When using the new MotionLayout, specifically when adding a KeyPosition element to the scene file.
My scene file for reference:
<?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/collapsed"
app:constraintSetStart="#id/expanded">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#id/recyclerview"
app:touchAnchorSide="top" />
<KeyFrameSet>
<KeyAttribute
app:framePosition="60"
app:target="#id/toolbar_image">
<CustomAttribute
app:attributeName="imageAlpha"
app:customIntegerValue="255" />
</KeyAttribute>
<KeyAttribute
app:framePosition="90"
app:target="#id/toolbar_image">
<CustomAttribute
app:attributeName="imageAlpha"
app:customIntegerValue="0" />
</KeyAttribute>
<KeyPosition
app:type="pathRelative"
app:framePosition="50"
app:target="#id/title"
app:percentX="0.9" />
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/expanded">
<Constraint
android:id="#id/toolbar_image"
android:layout_height="200dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="24dp"
android:scaleX="1.0"
android:scaleY="1.0"
app:layout_constraintBottom_toBottomOf="#id/toolbar_image"
app:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="#+id/collapsed">
<Constraint
android:id="#id/toolbar_image"
android:layout_height="?attr/actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#id/title"
android:layout_marginStart="20dp"
android:layout_marginBottom="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="0.625"
android:scaleY="0.625"
app:layout_constraintBottom_toBottomOf="#id/toolbar_image"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#id/toolbar_image" />
</ConstraintSet>
I am using Android Studio 3.2 stable, and AndroidX varients of the support libs & constraint layout.
Any help is appreciated :)
For your information, target
has been changed to motionTarget
in KeyPosition and KeyAttribute
Nevermind :)
Attribute "type" on KeyPosition element has been changed in Alpha 2 to be "keyPositionType"
here is a snippet if anyone is having the same issues:
<KeyPosition
app:keyPositionType="pathRelative"
app:framePosition="50"
app:target="#id/title"
app:percentX="0.9" />
instead of this:
<KeyPosition
app:type="pathRelative"
app:framePosition="50"
app:target="#id/title"
app:percentX="0.9" />
Update:
As #MichałK mentioned in comments in seems to be that
android:interpolator have changed to motion:motionInterpolator
in a later version
Reference: https://developer.android.com/reference/android/support/constraint/motion/MotionLayout.html#transition
Old Post:
In addition to what #Momen mentioned
In <Transition ...> tag motion:interpolator
have been changed to android:interpolator
( Change of namespace from motion to android )
example:
<Transition ...
android:interpolator="#android:anim/accelerate_interpolator">

Categories

Resources