android - 如何在 MotionLayout 中创建带有约束的幻灯片动画?
问题描述
运动布局:
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
app:layoutDescription="@xml/activity_main_scene">
<FrameLayout
android:id="@+id/left_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0c0"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="right text"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="left text"
android:textColor="#33691E" />
</FrameLayout>
<FrameLayout
android:id="@+id/bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#c00"
tools:ignore="SpeakableTextPresentCheck"
tools:layout_editor_absoluteX="918dp">
<View
android:layout_width="50dp"
android:layout_height="match_parent"
android:clickable="false" />
</FrameLayout>
<FrameLayout
android:id="@+id/right_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#00c"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_gravity="right"
android:text="right text"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_gravity="left"
android:text="left text"
/>
</FrameLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
场景:
<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/apk/res-auto"
>
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@id/left_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:visibility="visible"
android:alpha="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/bar"
/>
<Constraint android:id="@id/bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintRight_toRightOf="parent"
/>
<Constraint android:id="@id/right_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="@id/bar"
app:layout_constraintRight_toRightOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@id/left_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:alpha="1"
/>
<Constraint android:id="@id/bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<Constraint android:id="@id/right_content"
android:visibility="visible"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="@id/bar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</ConstraintSet>
<Transition
app:constraintSetStart="@+id/start"
app:constraintSetEnd="@id/end">
<!-- <OnClick app:targetId="@id/bar" app:clickAction="toggle" />-->
<OnSwipe app:touchAnchorId="@id/bar" app:dragDirection="dragLeft" />
</Transition>
</MotionScene>
我需要使用旧动画来应用这样的翻译动画:
<translate android:fromXDelta="0%"
android:toXDelta="-100%"
android:duration="150"
/>
当前动画是调整消失视图的大小,但我需要翻译动画,如何实现?
解决方案
最后,我解决了这个问题,至少很难说:要在不调整内容大小的情况下实现幻灯片动画,您需要 2 个屏幕外布局,它们重新创建可以推入或拉出可见内容的想象空间。
第一个屏幕外缓冲区(位于可见布局的左侧)将是镜像可见布局(不是完整副本,而是顶层容器的蓝图)。
第二个屏幕外缓冲区(位于可见布局的右侧)将是可见布局的副本。
重要提示:布局的不可见部分必须受到约束,因为它对用户可见,以避免将动画从 0 调整为目标大小
很难描述,但更容易显示结果:
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
app:layoutDescription="@xml/activity_main_scene">
<View
android:id="@+id/off_screen_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<View
android:id="@+id/off_screen_left_content"
android:layout_width="0dp"
android:layout_height="0dp"
/>
<FrameLayout
android:id="@+id/off_screen_left_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<View
android:layout_width="50dp"
android:layout_height="match_parent"
/>
</FrameLayout>
<View
android:id="@+id/off_screen_right"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<FrameLayout
android:id="@+id/off_screen_right_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<View android:layout_width="50dp"
android:layout_height="match_parent"
/>
</FrameLayout>
<View android:id="@+id/off_screen_right_content"
android:layout_width="0dp"
android:layout_height="0dp"
/>
<FrameLayout
android:id="@+id/left_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0c0"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="right text"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="left text"
android:textColor="#33691E" />
</FrameLayout>
<FrameLayout
android:id="@+id/bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#c00"
tools:ignore="SpeakableTextPresentCheck">
<View
android:layout_width="50dp"
android:layout_height="match_parent"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/right_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#00c"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_gravity="right"
android:text="right text"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_gravity="left"
android:text="left text"
/>
</FrameLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
和场景:
<?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/apk/res-auto"
>
<ConstraintSet android:id="@+id/off_screens">
<Constraint android:id="@id/off_screen_left"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintRight_toLeftOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="1"
/>
<Constraint android:id="@id/off_screen_left_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="@id/off_screen_left"
/>
<Constraint android:id="@id/off_screen_left_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="@id/off_screen_left_bar"
app:layout_constraintRight_toRightOf="@id/off_screen_left"
/>
<Constraint android:id="@id/off_screen_right"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="1"
/>
<Constraint android:id="@id/off_screen_right_bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintRight_toRightOf="@id/off_screen_right"
/>
<Constraint android:id="@id/off_screen_right_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="@id/off_screen_right"
app:layout_constraintRight_toLeftOf="@id/off_screen_right_bar"
/>
</ConstraintSet>
<ConstraintSet android:id="@+id/start"
app:deriveConstraintsFrom="@id/off_screens">
<Constraint android:id="@id/left_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/bar"
/>
<Constraint android:id="@id/bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintRight_toRightOf="parent"
/>
<Constraint android:id="@id/right_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="@id/off_screen_right_content"
app:layout_constraintRight_toRightOf="@id/off_screen_right_content"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end" app:deriveConstraintsFrom="@id/off_screens">
<Constraint android:id="@id/left_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="@id/off_screen_left_content"
app:layout_constraintRight_toRightOf="@id/off_screen_left_content"
/>
<Constraint android:id="@id/bar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<Constraint android:id="@id/right_content"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="@id/bar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</ConstraintSet>
<Transition
app:constraintSetStart="@+id/start"
app:constraintSetEnd="@id/end">
<OnSwipe app:touchAnchorId="@id/bar"
app:dragDirection="dragLeft" />
</Transition>
</MotionScene>
推荐阅读
- flutter - 使用会话令牌限制 Flutter 中的国家和引用
- arrays - 检查 IF 语句时,有没有办法让表中的列名等于字符串?
- android - 在 Activity 中使用 FirebaseAuthUI 和 Navigation 组件
- amazon-s3 - AWS S3:是否可以在不使用拒绝的情况下授予对除一个之外的所有存储桶的访问权限
- wordpress - 自定义 Woocommerce 登录页面
- asp.net - 如何向 System.Web.UI.WebControls.WebControl 添加新的布尔属性?
- c# - 当 autoOpen 为 False 时,JQuery 对话框未从 C# 代码后面打开
- javascript - 调用“getAllItems”函数时,React Native Async Storage 总是返回“undefined”
- django-models - 我未能将我的形状文件上传到 geodjango 数据库出现此错误
- reactjs - 我可以创建 2 个共享状态的组件吗?