Activity布局定义activity_motion.xml
<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/motionLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#888888"
app:layoutDescription="@xml/scene_01"
tools:showPaths="true">
<View
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/bottom"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/shape_top_corner"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/floating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@drawable/baseline_upload_24"
app:fabSize="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.motion.widget.MotionLayout>
- 主要控制View(button)动画带动底部变化
app:layoutDescription="@xml/scene_01"绑定 scene_01.xml
- MotionLayout继承
ConstraintLayout
定义 res/xml/scene_01.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@+id/start">
<OnSwipe
motion:dragDirection="dragDown"
motion:touchAnchorId="@+id/button"
motion:touchAnchorSide="bottom"
/>
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/button"
android:layout_width="108dp"
android:layout_height="192dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
Transition捆绑开始结束动作ConstraintSet
ConstraintSet定义起始结束布局容器
Constraint定义布局样式位置大小属性参照ConstraintLayout
OnSwipe指定要捆绑的布局锚点、配置拖拽方向
Activity代码中点击控制
enableEdgeToEdge()
setContentView(R.layout.activity_motion)
val motionLayout = findViewById<MotionLayout>(R.id.motionLayout)
ViewCompat.setOnApplyWindowInsetsListener(motionLayout) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
motionLayout.setTransitionDuration(1000)
val floating = findViewById<FloatingActionButton>(R.id.floating)
floating.setOnClickListener { v ->
println("-------${motionLayout.progress}-------")
if (motionLayout.progress == 0.0f) {
motionLayout.transitionToEnd {
if (motionLayout.progress == 0f) {
floating.setImageDrawable(
ContextCompat.getDrawable(
v.context,
R.drawable.baseline_upload_24
)
)
} else {
floating.setImageDrawable(
ContextCompat.getDrawable(
v.context,
R.drawable.baseline_download_24
)
)
}
println("transitionToEnd-------${motionLayout.progress}-------")
}
} else {
motionLayout.transitionToStart()
}
}