Problems with empty initial constraint set & 'deriveConstraintsFrom' on motion layout - android

I currently going my first steps into motion layout.
The example I want to create is the following:
A motion layout with two FABs in it (a mini and a normal one). The image above shows the end state after clicking the normal sized FAB.
What I've tried:
Motion Layout (is part of an other layout file):
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/include"
app:motionDebug="SHOW_PATH"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/darker_gray"
android:layout_margin="8dp"
app:layoutDescription="#xml/menu_scene"
app:layout_constraintTop_toBottomOf="#id/text"
app:layout_constraintStart_toStartOf="#id/text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/images_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="#id/menu_button"
app:layout_constraintTop_toTopOf="#id/menu_button"
app:layout_constraintBottom_toBottomOf="#id/menu_button"
android:src="#drawable/ic_image"
app:fabSize="mini" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/menu_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:src="#drawable/ic_edit" />
</androidx.constraintlayout.motion.widget.MotionLayout>
MotionScene:
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<Transition
app:constraintSetStart="#+id/start"
app:constraintSetEnd="#+id/end">
<OnClick
app:targetId="#+id/menu_button"
app:clickAction="toggle" />
</Transition>
<!-- pulls constraints from layout -->
<ConstraintSet android:id="#+id/start" />
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#id/images_button">
<Layout
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</Constraint>
</ConstraintSet>
</MotionScene>
But unfortunately with this configuration I got this:
The tiny pink dot on the bottom left is the mini FAB.
Because I heard about deriveConstraintsFrom I gave it a chance:
<MotionScene ...>
<Transition ...>
...
</Transition>
<ConstraintSet android:id="#+id/start" />
<ConstraintSet
android:id="#+id/end"
app:deriveConstraintsFrom="#id/start">
<Constraint android:id="#id/images_button">
...
</Constraint>
</ConstraintSet>
</MotionScene>
But I got the same result! :(
The only way I got the wanted result was with the following constraint set configuration:
<MotionScene ...>
...
<ConstraintSet android:id="#+id/start" />
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#id/images_button">
<!-- duplicated the layout properties from the initial layout :( -->
<Layout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="#id/menu_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</Constraint>
</ConstraintSet>
</MotionScene>
Wrap up:
I thought the empty constraint set <ConstraintSet android:id="#+id/start" /> pulls the its contrains from the layout itself and app:deriveConstraintsFrom="#id/start" on the other constraint set specifies all constraints from the initial constraint set and overwrites its own.
Can somebody tell me why this isn't working? Or did I miss something?
Thanks, Chris
PS.: I using androidx.constraintlayout:constraintlayout:2.0.0-beta4

Related

Android Motion Layout does not adapt to dynamic change in TextView content before animation. So how to make it adapt to new contents?

If we programmatically change the content of a Textview, after that the Motion animation only consider the original height of the TextView.
This example is suppose to expand to show a textView contents. It works if the content is previously assigned in the xml layout. But if the content is assigned programmatically and it takes several lines it only expand one line.
Code to trigger the Motion Scene Transition:
binding.button.setOnClickListener {
binding.tvLorem.text = LongText
binding.motionLayout.transitionToEnd()
}
<?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"
android:id="#+id/motionLayout"
tools:context=".MotionaLayoutActivity"
tools:showPaths="true"
app:layoutDescription="#xml/activity_motiona_layout_scene">
<View
android:id="#+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:background="#color/design_default_color_primary"
android:text="Button" />
<TextView
android:id="#+id/tvLorem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lorem Ipsum"
/>
<View
android:id="#+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="#color/design_default_color_secondary"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
The file with the MotionScene:
<?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">
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
motion:layout_constraintBottom_toTopOf="#id/tvLorem"
motion:layout_constraintEnd_toEndOf="parent" />
<Constraint
android:id="#+id/tvLorem"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="#dimen/default_margin"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toTopOf="#id/bottomBar">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#00000000"/>
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
motion:layout_constraintBottom_toTopOf="#id/tvLorem"
motion:layout_constraintEnd_toEndOf="parent" />
<Constraint
android:id="#+id/tvLorem"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/cardview_dark_background"
android:layout_marginTop="#dimen/default_margin"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintBottom_toTopOf="#+id/bottomBar">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#color/cardview_dark_background"/>
</Constraint>
</ConstraintSet>
<Transition
motion:constraintSetStart="#+id/start"
motion:constraintSetEnd="#+id/end"
motion:duration="1000">
<OnClick
motion:touchAnchorId="#+id/button"
motion:touchAnchorSide="right"
motion:dragDirection="dragRight" />
</Transition>
</MotionScene>
So, how to make it work changing the text content programmatically?
For the moment I tried:
binding.tvLorem.invalidate()
binding.tvLorem.postInvalidate()
binding.motionLayout.invalidate()
binding.motionLayout.clearAnimation()
binding.motionLayout.rebuildScene()
and nothing works!
What do works is changing the TextView visibility to GONE and VISIBLE before running the transition.
fun TextView.informMotionSceneAboutNewHeight(){
visibility = View.GONE
visibility = View.VISIBLE
}
binding.tvLorem.text = LongText
binding.tvLorem.informMotionSceneAboutNewHeight()
binding.motionLayout.transitionToEnd()

MotionLayout Group Visibility Issue

I have a Constraint Layout which contains a RecyclerView, a TextInputEditText, a Constraint Group (which handles visibility of the RecyclerView and TextInputEditText, an ImageView and a LottieAnimationView.
It works as this:
On startup, only the LottieAnimation is visible until my LiveData fetches data from repo and updates successfully.
After data is fetched, the LottieView is hidden and the Group visibility is shown which in turns shows the RecyclerView and TextInputEditText.
The ImageView is shown only if there's an error and then all other views are hidden except the ImageView.
Now i want that when i scroll my RecyclerView, the TextInputEditText also scrolls. (I can't use NestedScrollView due to pagination lag when scroll).
I made use of MotionLayout. Except it is not working properly. My visibility is broken. My Lottie Animation is staying on the screen. My layouts are as such:
fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="ViewModel"
type="...AllServicesViewModel" />
<import type="android.view.View" />
</data>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/Root_All_Services"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/scene_all_services_header">
<ImageView
android:id="#+id/Illus_Error"
android:layout_width="350dp"
android:layout_height="350dp"
android:layout_margin="16dp"
android:contentDescription="#string/icd_error_services_unavailable"
android:scaleType="centerCrop"
android:src="#drawable/il_error"
android:visibility="#{ViewModel.message != null ? View.VISIBLE : View.GONE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="#drawable/il_error" />
<androidx.constraintlayout.widget.Group
android:id="#+id/Group_Main_Content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="#{ViewModel.loading || ViewModel.message != null ? View.GONE : View.VISIBLE}"
app:constraint_referenced_ids="TextField_Search,RecyclerView_Services" />
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/TextField_Search"
style="#style/Mes.TextField.Search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:drawablePadding="-24dp"
android:hint="#string/action_search"
android:text="#={ViewModel.searchQuery}"
android:imeOptions="actionSearch"
android:padding="24dp"
android:singleLine="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/RecyclerView_Services"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/TextField_Search" />
<com.airbnb.lottie.LottieAnimationView
android:id="#+id/Anim_Loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="#{!ViewModel.loading || ViewModel.message != null? View.GONE : View.VISIBLE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="#raw/raw_anim_loading_services" />
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
scene_all_services_header.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">
<OnSwipe
motion:dragDirection="dragUp"
motion:onTouchUp="stop"
motion:touchAnchorId="#+id/TextField_Search" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/TextField_Search"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<ConstraintOverride
android:id="#+id/RecyclerView_Services"
motion:visibilityMode="ignore" />
<Constraint
android:id="#+id/Anim_Loading"
motion:visibilityMode="ignore" />
<Constraint
android:id="#+id/Illus_Error"
motion:visibilityMode="ignore" />
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/TextField_Search"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toTopOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent" />
<ConstraintOverride
android:id="#+id/RecyclerView_Services"
motion:visibilityMode="ignore" />
<Constraint
android:id="#+id/Anim_Loading"
motion:visibilityMode="ignore" />
<Constraint
android:id="#+id/Illus_Error"
motion:visibilityMode="ignore" />
</ConstraintSet>
</MotionScene>
Below are samples of how it worked before and after adding MotionLayout
Before
After
Can someone please help me out ?
<Constraint
android:id="#+id/RecyclerView_Services"
motion:visibilityMode="ignore" />
The above eliminates all constraint on this view!
<Constraint android:id="#+id/RecyclerView_Services">
<PropertySet motion:visibilityMode="ignore"/>
</Constraint>
The above removes all attributes leaving just the ignore.
2.1 supports...
<ConstraintOverride
android:id="#+id/RecyclerView_Services"
motion:visibilityMode="ignore" />
Which will do what you were expecting.
ConstraintOverride:
adds or modifies attributes
is not is not well supported by the IDE.
does not support layout_constraint{Top,Bottom,Left,Right,Start,End}_*=".."

android motionLayout's CustomAttribute - how to specifiy a background color from drawable resources

IN androids motionLayout i need to change the color while the view transitions. but it seems to not take resource links such as "#drawable/myshape". it wants raw values like "#FFFFFF". here is what i have done so far:
<?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
android:id="#+id/transition"
app:constraintSetEnd="#id/end"
app:constraintSetStart="#id/start"
app:motionInterpolator="linear"
app:moveWhenScrollAtTop="true">
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/spaceShip"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<!-- <CustomAttribute-->
<!-- app:attributeName="backgroundColor"-->
<!-- app:customColorValue="#drawable/space_spaceShip_bg" />-->
//the above code does not work. it wants a raw value, how to specify it from a drawable as i created a custom background shape already for my background.
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/spaceShip"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<CustomAttribute
app:attributeName="backgroundColor"
app:customColorValue="#FFFFFF" /> //also here how to specify #color/white instead of raw value
</Constraint>
</ConstraintSet>
</MotionScene>
it seems the way to do this is to find a property of some view that has a setter that scales from 0 to 1. the [imageFilterView][1] class is one such.
it has a property called [setcrossfade][2]
so my motionlayout can look like this:
<?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
android:id="#+id/transition"
app:constraintSetEnd="#id/end"
app:constraintSetStart="#id/start">
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/myview"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<CustomAttribute
app:attributeName="crossfade"
app:customFloatValue="0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/myview"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" >
<CustomAttribute
app:attributeName="crossfade"
app:customFloatValue="1" />
</Constraint>
</ConstraintSet>
</MotionScene>
and in our layout file we can do this:
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/ml"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
app:layoutDescription="#xml/motion_scene">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="#+id/myview"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="#drawable/bg1"
app:altSrc="#drawable/bg2"
android:background="#drawable/bg1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.motion.widget.MotionLayout>
transition it how you want ..manually or using a swipe in the motion layout file. anyway afterwards, it will fade out one drawable and fade in another one. exactly what i wanted.
[1]: https://developer.android.com/reference/androidx/constraintlayout/utils/widget/ImageFilterView
[2]: https://developer.android.com/reference/androidx/constraintlayout/utils/widget/ImageFilterView#setCrossfade(float)

Change FAB background color with MotionLayout and MotionScene

I have a FloatingActionButton that I want to transition to another color with the use of MotionLayout and MotionScene.
This is my FAB in my layout file
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/motion_layout"
app:layoutDescription="#xml/map_activity_scene"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="75dp"
android:layout_marginEnd="32dp"
android:id="#+id/fab"
android:visibility="invisible"
app:backgroundTint="#color/lightPurple"
app:srcCompat="#drawable/ic_layers_24px"
app:tint="#color/white"
app:layout_constraintBottom_toBottomOf="#+id/map"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
And this is my MotionScene
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<Transition
app:constraintSetStart="#+id/start"
app:constraintSetEnd="#+id/end"
app:duration="400">
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="75dp"
android:layout_marginEnd="32dp"
android:id="#+id/fab"
android:visibility="visible"
app:backgroundTint="#color/lightPurple"
app:srcCompat="#drawable/ic_layers_24px"
app:tint="#color/white"
app:layout_constraintBottom_toBottomOf="#+id/map"
app:layout_constraintEnd_toEndOf="parent">
<CustomAttribute
app:attributeName="backgroundTint"
app:customColorValue="#color/lightPurple" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:backgroundTint="#color/map_fab_transform"
app:layout_constraintEnd_toEndOf="#+id/revealLayout"
app:layout_constraintStart_toStartOf="#+id/revealLayout"
app:layout_constraintBottom_toBottomOf="#+id/revealLayout"
app:layout_constraintTop_toTopOf="#+id/revealLayout">
<CustomAttribute
app:attributeName="backgroundTint"
app:customColorValue="#color/map_fab_transform" />
</Constraint>
</ConstraintSet>
</MotionScene>
When I run the scene the fab moves to its correct place but the color does not change nor does the icon get removed from it. It seems that any of the app properties do not get applied.
How do I change to color of the fab and remove the icon in the fab with MotionLayout?
app:backgroundTint="#color/lightPurple"
app:srcCompat="#drawable/ic_layers_24px"
app:tint="#color/white"
Constraint does not take any of these tags.
It only takes a limited set of tags
You will have to set those with custom attributes.
If you want MotionLayout to interpolate the custom attributes you must set them on start and end ConstraintSet.

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>

Categories

Resources