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?
Approach: Add the support Library in build. gradle file and add dependency in the dependencies section. With the help of this library we can inherit the BottomSheetDialogFragment which helps us to implement Bottom Sheet component.
MotionLayout is a layout type that helps you manage motion and widget animation in your app. MotionLayout is a subclass of ConstraintLayout and builds upon its rich layout capabilities. As part of the ConstraintLayout library, MotionLayout is available as a support library and is backwards-compatible to API level 14.
Bottom Sheet dialogs seem to be replacing regular Android dialogs and menus. The Bottom Sheet is a component that slides up from the bottom of the screen to showcase additional content in your application. A Bottom Sheet dialog is like a message box triggered by the user's actions.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With