java - 底页 + Android MotionLayout 实现
问题描述
我正在尝试使用 MotionLayout 实现底部工作表。它适用于微不足道的情况 - 当底部工作表应仅在屏幕的一半中可见时(例如)。但是当底部表扩展并填满整个屏幕时,我无法让它在场景中工作。
所以这里可以是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>
问题是当底部工作表处于全屏状态时 OnSwipe 不起作用,但在底部工作表处于半屏状态时工作。我想有机会使用滑动移动隐藏底部工作表。
如何解决这个问题?应该添加还是修改过渡?
解决方案
你的过渡只需要一点点调整,约束很好:
- 您不需要第三次过渡。如果您在同一方向上的不同状态之间滑动 - 或者实际上即使您改变方向,MotionLayout 也会负责干净地移动通过多个
onSwipe
转换。 - 您的第二个和第三个 ConstraintSets 实际上并没有改变您正在移动的片段底部边缘的位置,但是您指定场景应该根据该边缘相对于滑动手势来计算进度。我建议阅读MotionLayout 代码实验室,特别是第 9 课,它很好地说明了这个概念。结果,我将其更改
touchAnchorSide
为top
. duration
对OnSwipe
过渡没有任何意义,可以删除它dragUp
使用或真的无关紧要dragDown
,它最终会得到相同的基于手势的垂直动画。我认为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>
推荐阅读
- c++ - CRTP - 危险的内存访问?
- node.js - NodeJS 输出未显示在 Visual Studio 2017 中
- r - 使用 ggnetwork 绘制边缘线宽与其权重成正比的网络
- h2o - 在 H2O 中构建 GBM 和 DRF 时, score_each_iteration 是否与 score_tree_interval = 1 相同?
- ios - UIButton 如何同时监听其他 Button 的更改、UILabel 文本的更改以及 UITextView 的更改
- xml - Applescript 为 InDesign 文档中的所有图像分配 XML 标记
- java - Spring Data JPA Multi-FK Join
- php - 具有不同键的多维数组来格式化数据
- hyperlink - 试图从phpBB中访问的链接中删除下划线
- ruby-on-rails - 从购物车中删除项目并将此数量添加回 stock_quantity (rubyonrails)