繁体   English   中英

底片 + Android MotionLayout 实现

[英]Bottom sheet + Android MotionLayout implementation

我正在尝试使用 MotionLayout 实现底部工作表。 它适用于微不足道的情况 - 当底部工作表应仅在屏幕的一半中可见时(例如)。 但是当底部表扩展并填满整个屏幕时,我无法让它在场景中工作。

在此处输入图像描述

所以这里可以是3个状态:

  1. 底片隐藏
  2. 底页填满半屏
  3. 底页填满整个屏幕

这是布局:

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

这里570dp等于半屏(例如)

以及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>


问题是当底部工作表处于全屏 state 时 OnSwipe 不起作用,但在底部工作表处于半屏 state 时工作。 我想有机会使用滑动移动隐藏底部工作表。

如何解决这个问题? 应该添加还是修改过渡?

你的过渡只需要一点点调整,约束很好:

  • 您不需要第三次过渡。 如果您在同一方向上的不同状态之间滑动 - 或者实际上即使您改变方向,MotionLayout 也会负责干净地移动多个onSwipe转换。
  • 您的第二个和第三个 ConstraintSets 实际上不会更改您正在移动的片段底部边缘的 position,但您指定场景应根据该边缘相对于滑动手势计算进度。 我建议通过MotionLayout 代码实验室,特别是第 9 课,它很好地说明了这个概念。 结果,我将touchAnchorSide更改为top
  • durationOnSwipe过渡没有任何意义,可以删除它
  • 无论您使用dragUp还是dragDown ,它最终会得到相同的基于垂直手势的 animation。 我认为在这种情况下, dragUp更容易理解。

修改后的过渡:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM