I want to use MotionLayout to implement the Bottom Sheet in my activity.
Motion scene:
<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">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="#id/bottomSheet"
motion:touchRegionId="#id/bottomSheet" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="0dp"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintSet>
</MotionScene>
Now, if I implement my MotionLayout like the following code, I can't dragUp in button area:
<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/ml"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
app:layoutDescription="#xml/activity_main_scene"
tools:context=".MainActivity">
<com.google.android.material.card.MaterialCardView
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#android:color/black">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/holo_red_dark"
android:padding="40dp">
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="A button" />
</FrameLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.motion.widget.MotionLayout>
I can wrap the MaterialCardView with a NestedScrollView then because the NestedScrollView will properly handle onInterceptTouchEvent, it will work:
<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/ml"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
app:layoutDescription="#xml/activity_main_scene"
tools:context=".MainActivity">
<androidx.core.widget.NestedScrollView
android:id="#+id/bottomSheet"
android:background="#android:color/holo_blue_dark"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#android:color/black">
<!-- other views -->
</com.google.android.material.card.MaterialCardView>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.motion.widget.MotionLayout>
If I implement the MotionLayout like this, I will face another issue. The MaterialCardView height does not change when the user drags up the view, even if I set the height to match_parent:
How can I change the code in a way that the red area covers the whole blue area?
Finally, I found the solution. I only need to add
android:fillViewport="true"
to the NestedScrollView to fix the issue. It happens because the height of NestedScrollView is bigger than its children in the end state, so I need to set fillViewport to true to resolve the issue.
Related
I'm having a lot of troubles figuring out how to use the MotionLayout to animate a Youtube-like bottom player bar.
After trying to understand how this layout works for a few hours using the official examples and a lot of googling, I stumbled upon this question which feature a GIF chowing exactly what I'm trying to achieve:
Unfortunately, the complete code is not there so I can't understand how the author did it.
All I have for now is this:
Two problems here: the animation instantly jumps from 0 to 100 and the view doesn't collapse, it keeps occupying the whole screen.
I don't know if it's related but that part of the UI is contained in a fragment. Here is the activity layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/surface"
app:layout_constraintBottom_toTopOf="#id/appbar_wrapper"
app:layout_constraintTop_toTopOf="parent">
<!--
This is the fragment that contains the view that lies
beneath the player controls. It's not visible on the image above
-->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
app:defaultNavHost="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:navGraph="#navigation/main_nav"
tools:layout="#layout/fragment_artists" />
<!--
This is the fragment that contains the fragemtn that contains
the controls that won't collapse
-->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/now_playing"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="audio.funkwhale.ffa.fragments.NowPlayingFragment" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is my fragment's UI:
<?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">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/now_playing_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/elevatedSurface"
android:orientation="vertical"
app:motionDebug="SHOW_ALL"
app:layoutDescription="#xml/fragment_now_playing_scene">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent" />
<SquareImageView
android:id="#+id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
android:padding="8dp"
app:srcCompat="#drawable/cover"
tools:src="#tools:sample/avatars" />
<!-- The rest of the UI is stripped to keep the code short -->
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
and my scene:
<?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/end"
app:constraintSetStart="#+id/start"
app:duration="1000"
app:motionInterpolator="linear" >
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#+id/header"
app:touchAnchorSide="top" />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="75"
app:motionTarget="#id/now_playing_details_controls" />
</KeyFrameSet>
<ConstraintSet android:id="#+id/start">
<Constraint android:id="#+id/header" />
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#id/header" />
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="#id/header"
app:layout_constraintBottom_toBottomOf="#id/header"
app:layout_constraintStart_toStartOf="#id/header" />
</ConstraintSet>
</Transition>
</MotionScene>
Edit
Thanks to hoford, I could resolve some of the problems. However, while animation works correctly, the layout itself doesn't move. This is how it should look like:
This implementation uses a simple FrameLayout in combination with BottomSheetBehavior instead of MotionLayout. The bottom sheet itself is fragment that uses databinding.
The current implementation using a MotionLayout looks like this:
As you can see, the parts of the UI in the fragment now animate correctly, but the FragmentContainerView itself doesn't collapse. I tried several combination of layout_height on the FragmentContainerView and the MotionLayout within but I can't replicate the behaviour of the BottomSheetBehavior implementation.
I feel like MotionLayout doesn't play well inside a FragmentContainerView and I couldn't find a case using fragments in Android's examples.
Here is the layout for the activity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<!-- The component displaying the albums list -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/surface"
app:layout_constraintVertical_weight="10"
app:layout_constraintTop_toTopOf="parent">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
app:defaultNavHost="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:navGraph="#navigation/main_nav"
tools:layout="#layout/fragment_artists" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- The fragment of the player controls bar that should collapse -->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/now_playing"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/appbar_wrapper"
android:name="audio.funkwhale.ffa.fragments.NowPlayingFragment" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/appbar_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="#style/AppTheme.AppBar"
app:backgroundTint="#color/elevatedSurface"
app:layout_insetEdge="bottom"
app:navigationIcon="#drawable/funkwhaleshape"
tools:menu="#menu/toolbar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is the updated layout of the player controls bar that should collape:
<?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>
<!-- snip -->
</data>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/now_playing_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/elevatedSurface"
app:motionDebug="SHOW_ALL"
app:layoutDescription="#xml/fragment_now_playing_scene">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<audio.funkwhale.ffa.views.SquareImageView
android:id="#+id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="0dp"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/cover"
tools:src="#tools:sample/avatars" />
<ImageButton
android:id="#+id/now_playing_details_info"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="8dp"
app:layout_constraintRight_toRightOf="#id/now_playing_details_cover"
app:layout_constraintTop_toTopOf="#id/now_playing_details_cover"
style="#style/IconButton"
android:layout_gravity="top|end"
android:background="#drawable/circle"
android:contentDescription="#string/alt_track_info"
android:src="#drawable/more"
app:tint="#color/controlForeground" />
<!-- Snip -->
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
And the updated scene:
<?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/end"
app:constraintSetStart="#+id/start"
app:duration="1000"
app:motionInterpolator="linear" >
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#+id/header"
app:touchAnchorSide="bottom" />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="10"
app:motionTarget="#id/now_playing_details_info"
/>
<KeyAttribute
android:alpha="0"
app:framePosition="10"
app:motionTarget="#id/now_playing_details_controls"
/>
</KeyFrameSet>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/now_playing_details_info"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="8dp"
app:layout_constraintRight_toRightOf="#id/now_playing_details_cover"
app:layout_constraintTop_toTopOf="#id/now_playing_details_cover"
/>
<Constraint
android:id="#+id/now_playing_details_controls"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="1"
app:layout_constraintTop_toBottomOf="#id/now_playing_details_cover"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="#id/header"
app:layout_constraintBottom_toBottomOf="#id/header"
app:layout_constraintStart_toStartOf="#id/header"
/>
<Constraint
android:id="#+id/now_playing_details_info"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="0dp"
android:alpha="0"
app:layout_constraintRight_toRightOf="#id/now_playing_details_cover"
app:layout_constraintTop_toTopOf="#id/now_playing_details_cover"
/>
<Constraint
android:id="#+id/now_playing_details_controls"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
app:layout_constraintTop_toBottomOf="#id/parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</ConstraintSet>
</Transition>
</MotionScene>
I suspect many things are wrong a few things I notice:
says to track the upward movement of the top of #id/header
But start and have the exact same
Which means the header does move
because app:layout_constraintTop_toTopOf="parent" + height="0dp"
implies it top is pinned.
In general before you think about the swipe part.
Focus on getting the two constraintSets to have the start and end state you want.
Which typically involves modifying constraints in the ConstraintSet
If it is laying out the way you want
Then the onSwipe anchor needs to be with the moving object
see https://youtu.be/XtnAZXM26wQ for a brief overview on onSwipe
The problem
You say "FragmentContainerView itself doesn't collapse"
But theFragmentContainerView is not a child of the MotionLayout.
Layouts can only control direct children. The only other thing a layout can do is change its wrap size. You seem to be trying to control the MotionLayouts Parent.
The way this would typically be done is motionLayout is at the base of everything you want to control.
You might be able to make the MotionLayout and the fragment transparent.
But you would still have touch handling missing.
I am trying to achieve a DrawerLayout like scene using MotionLayout. I have a home fragment and another card fragment that I want to come above home fragment when I swipe it from right. While everything works fine except that the card fragment comes in on swiping up instead of swiping left. For simplicity, I have replaced card fragment with a dummy ConstraintLayout. Below is my 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/ml_home_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/home_fragment_scene"
app:motionDebug="SHOW_ALL">
<include
android:id="#+id/home"
layout="#layout/layout_home_fragment" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/theme_main"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
MotionScene 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">
<Transition
app:constraintSetEnd="#id/end"
app:constraintSetStart="#id/start"
app:motionInterpolator="easeInOut">
<OnSwipe
app:onTouchUp="autoComplete"
app:touchRegionId="#id/card"
motion:dragDirection="dragLeft"
motion:touchAnchorId="#id/card"
motion:touchAnchorSide="left" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/home"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/card"
android:layout_width="20dp"
android:layout_height="match_parent"
android:layout_marginStart="-20dp"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleX="0.9"
android:scaleY="0.9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
I wanted to upload a screen recording as well but don't know why Logcat Screen Recorder doesn't seem to be working.
I tried many tutorials and documentations but none solved my issue. Please help. TIA!
My activity is something like
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#E7E7E7"
app:layout_constraintBottom_toTopOf="#+id/dummy"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="#+id/bottomSheet"
layout="#layout/bottom_sheet_persistent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<View
android:id="#+id/dummy"
android:background="#F44336"
android:layout_width="match_parent"
android:layout_height="80dp"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And the bottom sheet is as bottom_sheet_persistent.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="false"
app:behavior_peekHeight="80dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<View
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#2196F3"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The screenshot is
As you can understand from the xml that, the red part is just a static view and blue is the bottomsheet. The bottomsheet also works as expected. What I wanted to achieve is, when the user start scrolls from the static view (Red View), I would like to scroll up the bottomsheet.
Thanks in advance.
I'm using a fragment in a MotionLayout but the fragment view isn't filling the MotionLayout even though all constraints are set. Not only fragment, even any view, such as, LinearLayout doesn't expand and I get this :
If I change MotionLayout to ConstraintLayout it works fine and the fragment fills the parent.
Here is my layout xml code:
<?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">
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/motion_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
app:layoutDescription="#xml/scene_drawer"
tools:context=".activity.MainActivity">
<fragment
android:id="#+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="left"
app:defaultNavHost="true"
app:navGraph="#navigation/main"
/>
</androidx.constraintlayout.motion.widget.MotionLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navView"
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/navdrawer_menu"
app:headerLayout="#layout/nav_header"
/>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
I found the problem to be that in my motion scene xml, I needed to make the start and end constraint sets' width and height as match parent.
<?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="500"
motion:motionInterpolator="linear"
/>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#id/nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintWidth_default="percent"
motion:layout_constraintWidth_percent="1"
/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#id/nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="100dp"
android:scaleX="0.8"
android:scaleY="0.8"
android:translationX="100dp"
motion:layout_constraintWidth_default="percent"
motion:layout_constraintWidth_percent="1"
/>
</ConstraintSet>
</MotionScene>
I have a layout as such;
<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/motion_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical"
app:layoutDescription="#xml/motion_layout_details">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="#drawable/ic_back"
app:title="ToolbarTitle" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="244dp"
android:scaleType="fitXY" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
app:tabIndicator="#null"
app:tabMode="scrollable"
app:tabRippleColor="#null" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/vp_menu"
android:layout_width="0dp"
android:layout_height="0dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
With identical viewpager items that contain a recyclerview;
<androidx.constraintlayout.widget.ConstraintLayout
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:background="#color/white"
android:orientation="vertical"
android:paddingTop="#dimen/spacing_16dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingBottom="#dimen/spacing_24dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I have a motion scene that collapses the image when scrolled up (the configurations for this are correct). If in my viewpager items I wrap my RecyclerView in a nestedscrollview my transition -
<Transition
app:constraintSetEnd="#+id/end"
app:constraintSetStart="#+id/start"
app:duration="500"
app:motionInterpolator="linear">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#+id/vp_menu"
app:touchAnchorSide="top" />
</Transition>
Works just fine, and transitions as I'd expect. But removing that nested scrollview no longer triggers the motion layout at all. I've dug around for a good couple of hours and can't seem to find any explanation. I could put the nestedscrollview back in, but ideally I'd like to leave it out as A) it's not needed and B) breaks some stickheader stuff I'm using.
UPDATE
Fixed this as per my comment. .isNestedScrollingEnabled = false stops the recyclerview communicating with the motionlayout.
Turns out, from when I had my recyclerview in a nestedscrollview I had rv?.isNestedScrollingEnabled = false which must be stopping some kind of trigger for the motionlayout. Removing this has fixed the issue and works with the above code.