Android新控件MotionLayout介绍
Posted microhex
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android新控件MotionLayout介绍相关的知识,希望对你有一定的参考价值。
文章目录
上两章内容:
Android新控件MotionLayout介绍(一)
Android新控件MotionLayout介绍(二)
原文地址为:https://medium.com/google-developers/introduction-to-motionlayout-part-iii-47cd64d51a5
这一节主要讲述将MotionLayout与已经存在的Layout,比如CoordinatorLayout、DrawerLayout 或者ViewPager将如何一起使用。
实例
以下是Motionlayout与CoordinatorLayout 、 DrawerLayout 、 ViewPager 、 Lottie之间的相互集成:
CoordinatorLayout | DrawerLayout | ViewPager | Lottie |
---|---|---|---|
MotionLayout 与 CoordinatorLayout
【MotionLayout可以实现CoordinatorLayout类似的效果,在接下来的文章中将会有例子】
我们很容易利用MotionLayout来指定屏幕中组件怎么实现动画。同样,你可以在已经存在的布局中添加更多有趣的操作,这样的操作并不会对你的程序造成损害。
举个例子,如果你想搞一个这样的动作:
我们可以将在AppBarLayout中的Toolbar替换成为MotionLayout,从而我们可以让CoordinatorLayout 来实现这种动画。
我们可以通过setProgress()
来控制MotionLayout的动画的完成度,通过监听AppBarLayout的滚动改变来实现这个目的:
这个类名叫CollapsibleToolbar
,继承自MotionLayout
:
package com.google.androidstudio.motionlayoutexample.utils
import android.content.Context
import android.support.constraint.motion.MotionLayout
import android.support.design.widget.AppBarLayout
import android.util.AttributeSet
class CollapsibleToolbar @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr), AppBarLayout.OnOffsetChangedListener
override fun onOffsetChanged(appBarLayout: AppBarLayout?, verticalOffset: Int)
progress = -verticalOffset / appBarLayout?.totalScrollRange?.toFloat()!!
override fun onAttachedToWindow()
super.onAttachedToWindow()
(parent as? AppBarLayout)?.addOnOffsetChangedListener(this)
替换掉CoordinatorLayout
中的Toolbar,换上我们自定义的CollapsibleToolbar
:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
android:background="@color/contentBackground">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:theme="@style/AppTheme.AppBarOverlay">
<include layout="@layout/motion_09_coordinatorlayout_header"/>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_scrolling" />
</android.support.design.widget.CoordinatorLayout>
其中motion_09_coordinatorlayout_header布局如下,我们唯一要做的就是创建Motionlayout文件,包含需要动画的组件。
<?xml version="1.0" encoding="utf-8"?>
<com.google.androidstudio.motionlayoutexample.utils.CollapsibleToolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motionLayout"
app:layoutDescription="@xml/scene_09"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minHeight="50dp"
android:fitsSystemWindows="false"
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed">
<ImageView
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="@color/colorAccent"
android:scaleType="centerCrop"
android:src="@drawable/monterey"/>
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:transformPivotX="0dp"
android:transformPivotY="0dp"
android:text="Monterey"
android:textColor="#FFF"
android:textSize="32dp" />
</com.google.androidstudio.motionlayoutexample.utils.CollapsibleToolbar>
同样,我们定义一下动画描述文件scene_09:
<?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:constraintSetStart="@+id/start"
motion:constraintSetEnd="@+id/end" />
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="1.0"
motion:layout_constraintBottom_toBottomOf="parent"/>
<!-- 定义旋转的角度 -->
<Constraint
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:rotation="-90.0"
motion:layout_constraintBottom_toBottomOf="@+id/background"
motion:layout_constraintStart_toStartOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.2"
motion:layout_constraintBottom_toBottomOf="parent"/>
<Constraint
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:rotation="0.0"
motion:layout_constraintBottom_toBottomOf="@+id/background"
motion:layout_constraintStart_toStartOf="parent" />
</ConstraintSet>
</MotionScene>
MotionLayout 与 DrawerLayout
DrawerLayout是Android5.0出来的控件,说新也不新,感觉也用的蛮多的。我们称之为抽屉式布局,结合Motionlayout可以做一下比较炫酷的情景:
就像上面的CoordinatorLayout/AppBarLayout例子一样,我们需要定义一个子类来设置Motionlayout的动画完成度progress.我们称之为DrawerContent:
package com.google.androidstudio.motionlayoutexample.utils
import android.content.Context
import android.support.constraint.motion.MotionLayout
import android.support.v4.widget.DrawerLayout
import android.util.AttributeSet
import android.view.View
class DrawerContent @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : MotionLayout(context, attrs, defStyleAttr), DrawerLayout.DrawerListener
override fun onDrawerStateChanged(newState: Int)
override fun onDrawerSlide(drawerView: View, slideOffset: Float)
progress = slideOffset
override fun onDrawerClosed(drawerView: View)
override fun onDrawerOpened(drawerView: View)
override fun onAttachedToWindow()
super.onAttachedToWindow()
(parent as? DrawerLayout)?.addDrawerListener(this)
这个子类会自动的通过OnDrawerSlide
()的回调slideOffset
设置进度Progress
。
通过这个子类,在DrawaerLayout中使用MotionLayout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motionLayout"
android:background="@color/colorPrimaryDark">
<include layout="@layout/motion_12_drawerlayout_content"/>
<include layout="@layout/motion_13_drawerlayout_menu"/>
</android.support.v4.widget.DrawerLayout>
motion_12_drawerlayout_content.xml
是刚才上面例子的布局文件,我们简单拿过来用一下。
我们的菜单文件使用MotionLayout(或者我们刚刚自定义的DrawerContent):
[很简单,就是5个简单的TextView]
<?xml version="1.0" encoding="utf-8"?>
<com.google.androidstudio.motionlayoutexample.utils.DrawerContent
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/menu"
android:layout_width="180dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layoutDescription="@xml/scene_13_menu"
android:background="@color/colorPrimaryDark">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Monterey"
android:textSize="20sp"
android:textStyle="italic"
android:typeface="serif"
android:textColor="#FFF"
app:layout_constraintBottom_toTopOf="@+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Information"
app:fontFamily="sans-serif-smallcaps"
android:textColor="#FFF"
app:layout_constraintBottom_toTopOf="@+id/textView4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Directions"
app:fontFamily="sans-serif-smallcaps"
android:textColor="#FFF"
app:layout_constraintBottom_toTopOf="@+id/textView5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Sight-Seeing"
app:fontFamily="sans-serif-smallcaps"
android:textColor="#FFF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView4" />
<View
android:id="@+id/view"
android:background="#c2c1c1"
android:layout_width="100dp"
android:layout_height="1dp"
android:layout_marginTop="16dp"
app:layout_constraintBottom_toTopOf="@+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="California"
android:textColor="#FFF"
app:fontFamily="cursive"
app:layout_constraintBottom_toTopOf="@+id/view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" 以上是关于Android新控件MotionLayout介绍的主要内容,如果未能解决你的问题,请参考以下文章