炫酷!MotionLayout 使用介紹 (第一章)

MotionLayout  是ConstrainLayout 2.0庫中被引入的一個新類,幫助安卓開發者關聯手勢和組件動畫。接下來的文章將介紹會如何在應用中添加和使用MotionLayoutjava

第一章將介紹MotionLayout的基礎:android

  • MotionLayout 是什麼?
  • ConstrainLayout 2.0MotionLayout添加到項目中
  • 如何使用 MotionLayout
  • ConstraintSets
  • MotionScene
  • 示例1:關聯已有的佈局文件
  • 處理OnSwipe
  • 示例2:自包含的MotionScene
  • MotionLayout屬性
  • 總結

你能夠在這裏查看示例的源碼ConstraintLayout examples github repositorgit

MotionLayout是什麼?

安卓系統框架中已經提供下面幾種方法在應用中使用動畫:github

  • 動畫矢量Drawable
  • 屬性動畫框架
  • LayoutTransition動畫
  • 使用TransitionManager進行佈局轉換
  • CoordinatorLayout

這一部分將介紹MotionLayout與這些動畫的不一樣。MotionLayout就像它的名字同樣,首先它是一個佈局,能夠放置組件。其次它仍是ConstrainLayout的子類,內置豐富的功能。建立MotionLayout的目的是用於下降佈局過渡動畫和複雜的手勢處理之間的難度,你能夠認爲它擁有綜合屬性動畫TransitionManager,和CoordinatorLayout的功能。面試

它擁有綜合屬性動畫 TransitionManager,和 CoordinatorLayout的功能

使用MotionLayout你能夠像TransitionManager同樣經過兩個佈局文件描述佈局的過渡動畫,可是可使用任何屬性(不只僅局局於佈局屬性)。還有它支持可循跡的過渡,就像CoordinatorLayout(能夠經過滑動即刻響應過渡動畫)。它支持經過滑動和關鍵幀自定義過渡動畫。架構

MotionLayout是徹底聲明式的

MotionLayout 的另一個關鍵區別是,它是徹底聲明式的。只須要XML文件就能夠描述一個複雜的過渡動畫(若是你像經過代碼來描述動畫,系統提供的屬性徹底能夠知足需求)。app

MotionLayout工具

咱們相信這種聲明式的規範將簡化過渡動畫,同時也有助於爲 Android Studio 提供更好的圖形化工具。(咱們如今正在積極的開發這樣的工具,它如今還不可用。)框架

最後,做爲ConstrainLayout 2.0的一部分,它最低支持安卓API 14,99.8%的設備均可以使用。ide

限制

不一樣於TransitionManagerMotionLayout只能用於他的直接子組件。工具

什麼時候使用MotionLayout

咱們設想到的使用MotionLayout的使用場景:當你須要移動,縮放或者動畫實際的UI組件(按鈕,標題欄等)來提供與用戶的互動時。

如何使用MotionLayout

將ConstrainLayout 2.0和MotionLayout添加到項目中,只須要將下面的代碼添加到Gradle文件中便可

dependencies {
    implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1'
}

MotionLayoutConstrainLayout的子類,所以你能夠把它看成一個普通的佈局。將已經存在的ConstrainLayout佈局轉換成MotionLayout佈局只須要將類名從:

<android.support.constraint.ConstraintLayout .../>

替換成

<android.support.constraint.motion.MotionLayout .../>

ConstrainLayout和MotionLayout的主要不一樣是MotionLayout不是必須將實際描述信息包含在XML佈局文件中。MotionLayout一般將這些信息保存在一個單獨的XML文件(MotionScene)中並關聯到佈局文件,經過這種方式佈局文件只須要包含它們的屬性,無需包含位置信息和動畫。

ConstraintSets

一般ConstrainSet將全部遊戲佈局文件中的全部的位置信息規則; 你可使用多個ConstrainSet,你能夠決定將那些規則應用到佈局中,在應用時這些查看不會被重建,只會修改他們的位置和大小。結合TransitionManager使用能夠很容易的建立ConstrainLayout的動畫。MotionLayout實際上也是源於這種思想,並添加了更豐富的功能。

MotionScene

MotionLayout的規範保存在一個單獨的MotionSceneXML文件中,文件該存儲在res / xml目錄中。

image

一個MotionScene文件能夠全部遊戲動畫所需的所用內容:

  • 包含的 ConstraintSets
  • 這些ConstraintSet之間的轉換(過渡)
  • 關鍵幀,事件處理

例如,你能夠將一個查看從屏幕的一側拖拽到另外一側:

示例1:關聯佈局文件

須要你使用ConstrainLayout建立³³兩個ConstrainSet一個的英文初始位置(組件在屏幕的左面)一個是結束位置(組件在屏幕的右邊)

初始位置:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/button"
        android:background="@color/colorAccent"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginStart="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

結束位置:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/button"
        android:background="@color/colorAccent"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_marginEnd="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

使用這兩個佈局文件能夠初始化兩個ConstrainSet,並使用他們(使用若是TransitionManager會有動畫的平滑過渡)。這種方式有一個問題是轉化一旦開始就不會結束,你也不能告訴系統將轉換挺在某個位置(你不能經過輸入事件控制轉換)。MotionLayout解決了這些問題。你可使用MotionLayout作一樣的事,而且複用已存在的佈局文件來初始化狀態。首先須要爲組件建立一個MotionLayout文件(motion_01_basic.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"
    app:layoutDescription="@xml/scene_01"
    tools:showPaths="true">

    <View
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:background="@color/colorAccent"
        android:text="Button"
        tools:layout_editor_absoluteX="147dp"
        tools:layout_editor_absoluteY="230dp" />

</androidx.constraintlayout.motion.widget.MotionLayout>

文件佈局引用中了一個MotionScene文件scene_01

<?xml version="1.0" encoding="utf-8"?>
<MotionScene
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetStart="@layout/motion_01_cl_start"
        motion:constraintSetEnd="@layout/motion_01_cl_end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />
    </Transition>

</MotionScene>

scene_01設置了默認的轉換,設置了開始和結束ConstrainSet  (motion_01_cl_startmotion_01_cl_end),並轉換爲設置了OnSwipe處理。

OnSwipe

scene_01.xml文件中咱們在Transition中設置了OnSwipe處理器。處理器經過匹配用戶的輸入事件控制轉換。

image

有一些屬性你須要瞭解:

  • touchAnchorId:須要跟蹤的對象
  • touchAnchorSide:跟蹤手指的一側(右/左/上/下)
  • dragDirection:跟蹤手指運動的方向(dragRight / dragLeft / dragUp / dragDown將決定進度值的變化0-1)

示例2:自包含的MotionScene

示例1展現瞭如何快速的建立一個MotionLayout。,使用名單最終已了存在的佈局文件MotionLayout還請當即獲取iTunes直接在MotionScene文件中定義ConstraintSet。這樣作有有如下好處:

  • 一個文件能夠包含多個 ConstraintSet
  • 除了已有的功能外,還能夠處理其餘的屬性和自定義屬性
  • 面向將來:即將到來的Android Studio MotionEditor可能只支持自包含MotionScene文件
插值屬性

MotionScene中文件ConstraintSet元素可使用的屬性不只全部遊戲經常使用的佈局屬性,位置除了狀語從句:邊距下面的屬性也。能夠在MotionLayout中使用:

alpha
visibility
elevation
rotation, rotation[X/Y]
translation[X/Y/Z]
scaleX/Y

讓咱們爲示例1從新建立一個新的自包含的MotionScene。文件MotionLayout文件除了引用了新的scene_02.xml狀語從句:實例1中沒有區別:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.MotionLayout
    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_02"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/button"
        android:background="@color/colorAccent"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:text="Button" />

</android.support.constraint.motion.MotionLayout>

MotionScene文件中有明顯的區別,Transition的設置相同,可是咱們把Start和結束直接定義在了XML文件中。和普通佈局文件相比主要的區別是咱們沒有指定具體的組件,而是把限定屬性寫在了Constraint元素中。

<?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"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="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="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>

</MotionScene>

ConstraintSet

只須要將瞭解ConstrainSet是如何工做的,新的屬性將替換到關聯的組件上。只需將須要替換的屬性所有包含到Constraint中。一般這會清除組件上的所用屬性並將新的屬性賦值到組件上。MotionLayout的屬性

開發在中你可能會用到MotionLayout的下列屬性:

  • app:layoutDescription=」reference」指定MotionSceneXML文件
  • app:applyMotionScene=」boolean」 是否應用MotionScene [default = true]
  • app:showPaths=」boolean」是否顯示路徑[default = false]。記得在發佈版本中關閉
  • app:progress=」float」 指定轉換的進度[0-1]
  • app:currentState=」reference」 指定一個ConstraintSet

總結

第一篇文章包含了MotionLayout的基礎功能,你能夠在這裏查看源碼:https://github.com/googlesamples/android-ConstraintLayoutExamples

接下來的文章中咱們將包含更多的講解:

  • 自定義屬性,圖片變換,關鍵幀(第二部分)
  • 在現有的佈局中使用MotionLayout(CoordinatorLayout,DrawerLayout,ViewPager)(第三部分)
  • 關於關鍵幀的全部!(第四部分)
  • MotionLayout做爲根佈局
  • 嵌套MotionLayout&其餘的組件
  • MotionLayout和fragments

讀者福利限時分享

Android開發資料+面試架構資料 免費分享 點擊連接 便可領取

《Android架構師必備學習資源免費領取(架構視頻+面試專題文檔+學習筆記)》

相關文章
相關標籤/搜索