I am trying to implement Bottom sheet using MotionLayout. It works in a trivial case - when bottom sheet should be visible only in a half of screen (for example). But I can't make it work in a scenario when bottom sheet expands and fills whole screen.
So here can be 3 states:
Here is layout:
<androidx.constraintlayout.motion.widget.MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene_description">
<FrameLayout
android:id="@+id/fragmentPlaceholder"
android:layout_width="match_parent"
android:layout_height="570dp"
android:elevation="8dp"> some content here </FrameLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
Here 570dp
is equal to half screen (for example)
And the content of scene_description.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">
<Transition
android:id="@+id/transition1"
app:constraintSetStart="@id/bottomSheetHidden"
app:constraintSetEnd="@id/bottomSheetHalfOpen"
app:duration="300">
<OnSwipe
app:dragDirection="dragDown"
app:onTouchUp="autoCompleteToStart"
app:touchAnchorId="@+id/fragmentPlaceholder"
app:touchAnchorSide="bottom"/>
</Transition>
<Transition
android:id="@+id/transition2"
app:constraintSetStart="@id/bottomSheetHalfOpen"
app:constraintSetEnd="@id/bottomSheetOpenFullScreen"
app:duration="300">
</Transition>
<Transition
android:id="@+id/transition3"
app:constraintSetStart="@id/bottomSheetHidden"
app:constraintSetEnd="@id/bottomSheetOpenFullScreen"
app:duration="300">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@+id/fragmentPlaceholder"
app:touchAnchorSide="bottom" />
</Transition>
<ConstraintSet android:id="@+id/bottomSheetHidden">
<Constraint android:id="@id/fragmentPlaceholder">
<Layout
android:layout_width="match_parent"
android:layout_height="570dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="parent"/> <!-- below screen, not visible-->
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/bottomSheetHalfOpen"
app:deriveConstraintsFrom="@id/bottomSheetHidden">
<Constraint android:id="@id/fragmentPlaceholder">
<Layout
android:layout_width="match_parent"
android:layout_height="570dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/bottomSheetOpenFullScreen"
app:deriveConstraintsFrom="@id/bottomSheetHidden">
<Constraint android:id="@id/fragmentPlaceholder">
<Layout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</Constraint>
</ConstraintSet>
</MotionScene>
The problems is OnSwipe doesn't work when bottom sheet is in Full screen state, but works when bottom sheet is in half screen state. I want to have an opportunity to hide bottom sheet using swipe movement.
How this problem could be solved? Should transitions be added or modified?
Your transitions just needed a little tweaking, constraints were fine:
onSwipe
transitions.touchAnchorSide
to top
.duration
means nothing to OnSwipe
transitions, can just delete itdragUp
or dragDown
, it ends up with the same vertical gesture-based animation. I think dragUp
is a little more understandable in this case.Modified transitions:
<Transition
android:id="@+id/transition1"
app:constraintSetStart="@id/bottomSheetHidden"
app:constraintSetEnd="@id/bottomSheetHalfOpen">
<OnSwipe
app:dragDirection="dragUp"
app:onTouchUp="autoCompleteToStart"
app:touchAnchorId="@+id/fragmentPlaceholder"
app:touchAnchorSide="top"/>
</Transition>
<Transition
android:id="@+id/transition2"
app:constraintSetStart="@id/bottomSheetHalfOpen"
app:constraintSetEnd="@id/bottomSheetOpenFullScreen">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="@+id/fragmentPlaceholder"
app:touchAnchorSide="top" />
</Transition>