MotionLayout Group Visibility Issue - android

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}_*=".."

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

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)

Two Recycler Views inside a MotionLayout creating problems

I am new in using Motion Layout and I have used two Recycler views rv_horizontal and rv_vertical ,rv_horizontal is using LinearLayout Manger with horizontal orientation and rv_vertical is using GridLayout Manger. I have used both of them within Motion Layout. What I want is,when I scroll up the rv_vertical then rv_horizontal, along with the Text ViewtxtCategory, should disappear.
What I tried is following:
home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Home"
android:background="#color/bgcolor"
app:layoutDescription="#xml/fragment_home_scene">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="#+id/txtCategory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="#string/category"
android:textSize="8pt"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/txtCategory"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/txtFamousPlaces"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="#string/famous_places"
android:textSize="8pt"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/rv_horizontal" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_vertical"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/txtFamousPlaces"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.motion.widget.MotionLayout>
SceneFile of Home Fragment i.e., home_scene.xml :
<?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"
xmlns:motion="http://schemas.android.com/tools">
<ConstraintSet android:id="#+id/start">
<Constraint android:id="#+id/txtCategory"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Constraint
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="#id/txtCategory"
android:id="#+id/rv_horizontal"
app:layout_constraintBottom_toTopOf="#+id/txtFamousPlaces" />
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#id/txtCategory"
android:layout_width="0dp"
android:layout_height="wrap_content"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintBottom_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<Constraint
android:layout_height="0dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="#id/txtCategory"
android:id="#+id/rv_horizontal"
app:layout_constraintBottom_toTopOf="parent" />
</ConstraintSet>
<Transition
app:constraintSetEnd="#id/end"
app:constraintSetStart="#+id/start">
<OnSwipe
motion:onTouchUp="stop"
motion:dragDirection="dragUp"
motion:touchAnchorId="#+id/rv_vertical"
app:moveWhenScrollAtTop="true"/>
</Transition>
</MotionScene>
I am facing the following problems, if anyone knows please help me:
I am scrolling up the rv_vertical but nothing is happening , although I have set the attribute motion:touchAnchorId="#+id/rv_vertical" within OnSwipe attribute in home_scene.xml file. As you can see.
When I scroll up the FamousPlaces then scroll down it then recycler view rv_horizontal does not load completey. As following
I tell you again what I want is,when I scroll up the rv_vertical, rv_horizontal, along with the Text ViewtxtCategory, should disappear.And when I scroll down rv_vertical, rv_horizontal should loaded completely. If anybody knows please help me.

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

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

How to use motion layout with recyclerview

trying to use MotionLayout with RecyclerView,
when scrolling up, app is crashing with error:
android.content.res.Resources$NotFoundException: Unable to find
resource ID #0xffffffff
fragment layout code is
<android.support.constraint.motion.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"
app:layoutDescription="#xml/collapsing_config_order_details"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="#+id/tv_delivery_type"
app:layout_constraintStart_toStartOf="#+id/imageView15"
app:layout_constraintTop_toBottomOf="#+id/view4">
...
</android.support.v7.widget.CardView>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/cardView"
app:layout_constraintStart_toStartOf="#+id/cardView"
app:layout_constraintTop_toBottomOf="#+id/cardView" />
</android.support.constraint.motion.MotionLayout>
and layoutDescription code is:
<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:touchAnchorSide="top"
app:moveWhenScrollAtTop="#+id/rv_list" />
</Transition>
<ConstraintSet android:id="#+id/expanded"
android:id="#+id/cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="#+id/tv_delivery_type"
app:layout_constraintStart_toStartOf="#+id/imageView15"
app:layout_constraintTop_toBottomOf="#+id/view4" />
</ConstraintSet>
<ConstraintSet android:id="#+id/collapsed">
<Constraint
android:id="#+id/cardView"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="#+id/tv_delivery_type"
app:layout_constraintStart_toStartOf="#+id/imageView15"
app:layout_constraintTop_toBottomOf="#+id/view4" />
</ConstraintSet>
</MotionScene>
Add android:nestedScrollingEnabled="false" to your recyclerView
works for me.
app:moveWhenScrollAtTop="#+id/rv_list"
Vale of app:moveWhenScrollAtTop should be boolean.
Change
<ConstraintSet android:id="#+id/expanded"
android:id="#+id/cardView"
to
<ConstraintSet android:id="#+id/expanded" >
<Constraint android:id="#+id/cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="#+id/tv_delivery_type"
app:layout_constraintStart_toStartOf="#+id/imageView15"
app:layout_constraintTop_toBottomOf="#+id/view4" />
</ConstraintSet>
Each ConstraintSet should have Constraint by themselves and you need to specify as many Constraint as you want to change the scene, like if you want to move A and B together with one interaction, you need to specify both of them in one ConstraintSet
Also, I'm not sure what you're trying to achieve, but I think you need to write code like below
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#id/rv_list"
app:touchAnchorSide="top" />
That means you're targeting rv_list to trigger the action.

Categories

Resources