[譯]Constraint Layout 動畫 |動態(tài) Constraint |用 Java 實現(xiàn)的 UI(這到底是什么)[第三部分]

喔般堆,又是新的一天邑退,是時候?qū)W些新東西來讓今天變得精彩起來了。

各位讀者朋友你們好,希望各位一切順利晰搀。我們之前已經(jīng)在第一部分第二部分
中學(xué)習(xí)了許多關(guān)于 Constraint Layout 的新東西。現(xiàn)在是時候?qū)W習(xí)這個令人驚訝的布局剩下的部分了害幅。這一篇很有可能是關(guān)于 Constraint Layout系列的最后一篇文章了元旬。

動機:

寫這篇文章的動機和在第一部分討論的是一樣的。現(xiàn)在在這篇文章里我主要談?wù)摰氖顷P(guān)于 Constraint Layout 的動畫掺炭。關(guān)于這個主題有一個壞消息辫诅,那就是 Android 的開發(fā)文檔并沒有提供足夠的幫助。在開始這篇文章之前我想先道個歉涧狮,由于知識的欠缺我可能會在某些地方出現(xiàn)錯誤的觀點炕矮。但是我可以 100% 的保證通過我的講述么夫,最終你會喜歡并且適應(yīng)這些動畫。

我對這個主題的命名有些猶豫肤视,所以我決定使用三個名字組成的題目档痪,《Constraint Layout 動畫 |動態(tài) Constraint |用 Java 實現(xiàn)的 UI》。在這篇文章的最后邢滑,你會了解到為什么我選擇這三個名字腐螟。

現(xiàn)在我不打算講解 Constraint Layout 動畫 API 帶來的新特點,而是準(zhǔn)備和你們分享我在實現(xiàn)動畫效果時遇到的一些問題困后。那么讓我們開始吧乐纸。

我們需要下載 2.3 版本的 Android studio。在之前的版本里 Visual Editor 不太好摇予,在 Design Tab 里經(jīng)常會出現(xiàn)一些錯誤信息汽绢。所以下載 2.3 測試版的 Android studio 非常重要,這個版本在我寫這篇文章的時候是可以下載到的侧戴。

介紹:

在這篇文章里我們主要使用 Java 語言來工作宁昭,但是在開始之前我打算解釋下在這篇文章里一切是如何運作的。

我將基于上面的 APP 來進(jìn)行這篇文章的論述酗宋。我有一個 constraint layout 积仗,這里面總共有五個按鈕。

應(yīng)用和重置按鈕除了應(yīng)用和重置我們的動畫之外不做其他事情蜕猫。另外三個按鈕被用來進(jìn)行我們的動畫寂曹。我們通過應(yīng)用不同的動畫來使這三個按鈕共同協(xié)作。最重要的一點丹锹,我們在開始之前應(yīng)該知道這三個按鈕的 constraint稀颁。

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <Button
            android:id="@+id/applyButton"
            android:text="Apply"
            ...
            />

        <Button
            android:id="@+id/resetButton"
            android:text="Reset"
            ...
            />

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:text="Button 1"
            android:layout_marginLeft="52dp"
            app:layout_constraintLeft_toLeftOf="parent"
            android:layout_marginStart="52dp"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="69dp" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:text="Button 2"
            app:layout_constraintLeft_toRightOf="@+id/button1"
            android:layout_marginLeft="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginRight="8dp"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintHorizontal_bias="0.571"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="136dp" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:text="Button 3"
            android:layout_marginTop="102dp"
            app:layout_constraintTop_toBottomOf="@+id/button1"
            android:layout_marginLeft="88dp"
            app:layout_constraintLeft_toLeftOf="parent"
            android:layout_marginStart="88dp" />

    </android.support.constraint.ConstraintLayout>

在你檢查這段代碼之后你可以輕松地了解這三個按鈕之間的關(guān)系,下面這張圖會給你一個更直觀的認(rèn)識楣黍。

哈哈匾灶,我知道把這張圖與 XML 文件對照來看很容易理解。現(xiàn)在你了解了這三個按鈕互相之間的關(guān)系以及與父控件的關(guān)系租漂。
在深入的發(fā)掘之前我想再介紹一個新的 API阶女。

public class MainActivity extends AppCompatActivity {

    private ConstraintLayout constraintLayout;
    private ConstraintSet applyConstraintSet = new ConstraintSet();
    private ConstraintSet resetConstraintSet = new ConstraintSet();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        constraintLayout = (ConstraintLayout) findViewById(R.id.main);
        resetConstraintSet.clone(constraintLayout);
        applyConstraintSet.clone(constraintLayout);
    }

    public void onApplyClick(View view) {

    }

    public void onResetClick(View view) {

    }

留意粗體字,這些代碼很簡單哩治。 ConstraintSet 就是我們要在這個教程中經(jīng)常用到的一個 API秃踩。簡單來說,你可以這樣理解业筏,這個 API 將記住我們在 XML 文件里實現(xiàn)的所有的 constraints憔杨。怎樣使用呢?就像你看到的蒜胖,在上面的代碼里我擁有了一個 constarintLayout 引用消别,在那之后抛蚤,我將把它的 constraints 復(fù)制到我們的兩個變量 resetConstraintSetapplyConstraintSet 中。非常的簡單寻狂。

現(xiàn)在為了適應(yīng)新的要求岁经,我將改變我的寫作風(fēng)格。

我將為同樣的要求使用不同的語句蛇券,這樣你可以輕易的理解我這篇文章的標(biāo)題缀壤。

新需求:

我想要讓按鈕 1 動起來,當(dāng)用戶點擊啟動按鈕的時候纠亚,讓它與父控件的左邊對齊塘慕。你能幫我一下么?
用開發(fā)語言來說:

兄弟蒂胞,我想要在 constraint layout 里使用 Java 代碼讓按鈕 1 在用戶點擊啟動按鈕的時候與父控件的左邊對齊苍糠。你可以幫我一下么。

解決方案:

public void onApplyClick(View view) {
    applyConstraintSet.setMargin(R.id.button1,ConstraintSet.START,8);
    applyConstraintSet.applyTo(constraintLayout);
}

public void onResetClick(View view) {
    resetConstraintSet.applyTo(constraintLayout);
}

從現(xiàn)在開始我只向你展示 onApplyClick() 方法啤誊,其他的代碼始終是不變的。如果你看見了 onResetClick()方法拥娄,噢蚊锹,請你忘掉它。我會一直使用最初時的 constraints 來返回到最開始的 UI 界面

現(xiàn)在有兩個新的 API 方法稚瘾。setMargin() 和 applyTo()牡昆,我感覺沒有必要去解釋 applyTo() 方法。

SetMargin() 方法將使用三個參數(shù)(viewId, anchor, margin)摊欠。

按鈕 1 有 52dp 的左邊距丢烘,但是當(dāng)用戶點擊之后我會把間距改變到 8px。是時候看下這個過程了些椒。

除了猛地一跳播瞳,沒有按鈕移動的軌跡,這看起來并不像動畫免糕。所以我們需要重新檢查下我們的代碼赢乓。在檢查之后我發(fā)現(xiàn)需要在 applyButton() 方法里再加點東西。在增加了之后石窑,得到動畫效果如下圖所示牌芋。

好了。是時候?qū)徱曄滦麓a的變化了松逊。

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);
    applyConstraintSet.setMargin(R.id.button1,ConstraintSet.START,8);
    applyConstraintSet.applyTo(constraintLayout);
}

這里我需要添加 TransitionManager API躺屁。從一個 support library 里面能夠獲取到 TransistionManager API。你可以添加 gradle 依賴经宏。

compile 'com.android.support:transition:25.1.0'

在進(jìn)行下一步的操作之前犀暑。我想要復(fù)習(xí)下現(xiàn)在的操作驯击。

簡單來說我們只使用了兩個 API。ConstraintSet 和 TransitionManager母怜。從現(xiàn)在起我們將只使用 ConstraintSet API余耽。

新需求:

用戶語言:

當(dāng)用戶點擊應(yīng)用按鈕的時候,我想要讓所有的按鈕動起來并在父容器里水平居中苹熏。

開發(fā)者語言:

兄弟我想要當(dāng)用戶點擊應(yīng)用按鈕的時候通過使用 Java 代碼讓所有的按鈕在 constraint layout 里移動到水平居中的位置碟贾。你能幫我一下么?

解決方案:

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);
    applyConstraintSet.centerHorizontally(R.id.button1, R.id.main);
    applyConstraintSet.centerHorizontally(R.id.button2, R.id.main);
    applyConstraintSet.centerHorizontally(R.id.button3, R.id.main);
    applyConstraintSet.applyTo(constraintLayout);
}

這里我使用 centerHorizontally() 方法轨域。這個方法需要兩個參數(shù):

第一個:我想要進(jìn)行水平居中操作的 View袱耽。
第二個:父容器 View。

它并沒有像我們預(yù)期的那樣工作干发。在分析之后我發(fā)現(xiàn)了問題朱巨。我們給這些按鈕設(shè)置了不同的外邊距,這導(dǎo)致了我們點擊應(yīng)用按鈕時他們將移動到中心枉长,但是由于外邊距的設(shè)定冀续,它們最終的位置出現(xiàn)了偏移。是時候解決這個問題了必峰。

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);

    applyConstraintSet.setMargin(R.id.button1,ConstraintSet.START,0);
    applyConstraintSet.setMargin(R.id.button1,ConstraintSet.END,0);
    applyConstraintSet.setMargin(R.id.button2,ConstraintSet.START,0);
    applyConstraintSet.setMargin(R.id.button2,ConstraintSet.END,0);
    applyConstraintSet.setMargin(R.id.button3,ConstraintSet.START,0);
    applyConstraintSet.setMargin(R.id.button3,ConstraintSet.END,0);


    applyConstraintSet.centerHorizontally(R.id.button1, R.id.main);
    applyConstraintSet.centerHorizontally(R.id.button2, R.id.main);
    applyConstraintSet.centerHorizontally(R.id.button3, R.id.main);
    applyConstraintSet.applyTo(constraintLayout);
}

這里我把所有按鈕的左右外邊距都設(shè)置為 0洪唐。

新需求:

用戶的語言:
當(dāng)用戶點擊應(yīng)用按鈕的時候,我想讓按鈕 3 動起來吼蚁,然后移動到正中心凭需。

開發(fā)者的語言:

當(dāng)用戶點擊應(yīng)用按鈕的時候,我想要通過在 constraint layout 里使用 Java 代碼讓按鈕 3 移動到父控件的中心肝匆。你能幫我一下么粒蜈?

解決方案:

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);

    applyConstraintSet.setMargin(R.id.button3,ConstraintSet.START,0);
    applyConstraintSet.setMargin(R.id.button3,ConstraintSet.END,0);
    applyConstraintSet.setMargin(R.id.button3,ConstraintSet.TOP,0);
    applyConstraintSet.setMargin(R.id.button3,ConstraintSet.BOTTOM,0);

    applyConstraintSet.centerHorizontally(R.id.button3, R.id.main);
    applyConstraintSet.centerVertically(R.id.button3, R.id.main);

    applyConstraintSet.applyTo(constraintLayout);
}

我在這里先為四個邊緣設(shè)定為 0 像素的外邊距,然后我使用 centerHorizontal + centerVertical 方法旗国。

新需求:

用戶語言:
當(dāng)用戶點擊應(yīng)用按鈕的時候枯怖,我想要讓所有的按鈕的寬度都變化成 600 像素。

開發(fā)者語言:
當(dāng)用戶點擊應(yīng)用按鈕的時候粗仓,我想要通過在 constraint layout 里使用 Java 代碼讓所有按鈕的寬度尺寸都變成 600 像素嫁怀。你能幫我一下么?

解決方案:

    public void onApplyClick(View view) {
        TransitionManager.beginDelayedTransition(constraintLayout);

        applyConstraintSet.constrainWidth(R.id.button1,600);
        applyConstraintSet.constrainWidth(R.id.button2,600);
        applyConstraintSet.constrainWidth(R.id.button3,600);

        // applyConstraintSet.constrainHeight(R.id.button1,100);
        // applyConstraintSet.constrainHeight(R.id.button2,100);
        // applyConstraintSet.constrainHeight(R.id.button3,100);

        applyConstraintSet.applyTo(constraintLayout);

    }

上面展示的是我使用的 constraintWidth 方法借浊。


新需求:

用戶語言:

當(dāng)用戶點擊應(yīng)用按鈕的時候塘淑,我想要讓按鈕1的寬度和高度充滿整個屏幕并且讓其他的視圖隱藏。

開發(fā)者語言:
當(dāng)用戶點擊應(yīng)用按鈕的時候蚂斤,我想要通過在 constraint layout 里使用 Java 代碼讓按鈕1的寬度和高度都 match_parent存捺, 并且讓其他的視圖 gone,你能幫我一下么?

解決方案:

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);

    applyConstraintSet.setVisibility(R.id.button2,ConstraintSet.GONE);
    applyConstraintSet.setVisibility(R.id.button3,ConstraintSet.GONE);
    applyConstraintSet.clear(R.id.button1);
    applyConstraintSet.connect(R.id.button1,ConstraintSet.LEFT,R.id.main,ConstraintSet.LEFT,0);
    applyConstraintSet.connect(R.id.button1,ConstraintSet.RIGHT,R.id.main,ConstraintSet.RIGHT,0);
    applyConstraintSet.connect(R.id.button1,ConstraintSet.TOP,R.id.main,ConstraintSet.TOP,0);
    applyConstraintSet.connect(R.id.button1,ConstraintSet.BOTTOM,R.id.main,ConstraintSet.BOTTOM,0);
    applyConstraintSet.applyTo(constraintLayout);
}

我在上面用了一些新方法捌治,在這里我來解釋一下:

setVisibility:我覺得這個很簡單岗钩。

clear: 我想要把 view 上的所有 constraint 都清除掉。

connect: 我想要 view 上添加 constraint肖油。這個方法需要5個參數(shù)兼吓。

第一個:我想要在上面添加 constraint 的 view。

第二個:我準(zhǔn)備添加的 constraint 的邊緣狀態(tài)森枪。

第三個:constraint 的第一個 view视搏,它被用來作為我的錨點。

第四個:我的錨點 view 的邊緣狀態(tài)县袱。

第五:外邊距浑娜。

是時候開始進(jìn)一步的操作了。在教程2里我們已經(jīng)了解到了 Chaining 的概念了式散。我將向你們展示如何使用 Java 語言來實現(xiàn)它筋遭。

新需求:

用戶語言:
當(dāng)用戶點擊應(yīng)用按鈕的時候,我想要讓所有的按鈕都與屏幕的頂端對齊并且水平居中暴拄。

開發(fā)者語言:
當(dāng)用戶點擊應(yīng)用按鈕的時候漓滔,我想要通過在 constraint layout 里使用 Java 代碼來實現(xiàn)這三個按鈕的 packed chaining 邏輯。你能幫我一下么乖篷?

解決方案:

我接下來要講述的東西會有點超前次和,但我會把它當(dāng)成沒什么了不起的東西來解釋。所以各位準(zhǔn)備好那伐。

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);

    applyConstraintSet.clear(R.id.button1);
    applyConstraintSet.clear(R.id.button2);
    applyConstraintSet.clear(R.id.button3);

首先我把三個按鈕上的所有 constraint 都清除了。這是我個人的偏好石蔗,你可以只去掉按鈕的外邊距或者尺寸罕邀,其他方式也可以,但是我覺得這是最容易實現(xiàn)的方案⊙啵現(xiàn)在我們的按鈕沒有任何的 constraint诉探。(0 width, 0 height, 0 margin …)。

// button 1 left and top align to parent
applyConstraintSet.connect(R.id.button1, ConstraintSet.LEFT, R.id.main, ConstraintSet.LEFT, 0);

如上面展示的棍厌,現(xiàn)在我給按鈕 1 添加上左邊的 constraint肾胯。

// button 3 right and top align to parent
applyConstraintSet.connect(R.id.button3, ConstraintSet.RIGHT, R.id.main, ConstraintSet.RIGHT, 0);

如上面展示的,現(xiàn)在我給按鈕 3 添加上右邊的 constraint耘纱。

現(xiàn)在在你的腦海里勾勒出這些代碼形成的草圖敬肚,我們的按鈕 1 在父控件的左上角,按鈕 2 也一樣束析,不過相對靠右艳馒。

// bi-direction or Chaining between button 1 and button 2
applyConstraintSet.connect(R.id.button2, ConstraintSet.LEFT, R.id.button1, ConstraintSet.RIGHT, 0);
applyConstraintSet.connect(R.id.button1, ConstraintSet.RIGHT, R.id.button2, ConstraintSet.LEFT, 0);

如上所示,我在這里創(chuàng)建了按鈕 1 和按鈕 2 的雙向關(guān)系。

// bi-direction or Chaining between button 2 and button 3
applyConstraintSet.connect(R.id.button2, ConstraintSet.RIGHT, R.id.button3, ConstraintSet.LEFT, 0);
applyConstraintSet.connect(R.id.button3, ConstraintSet.LEFT, R.id.button2, ConstraintSet.RIGHT, 0);

如上所示弄慰,我在這里創(chuàng)建了按鈕 2 和按鈕 3 的雙向關(guān)系第美。

applyConstraintSet.createHorizontalChain(R.id.button1,
        R.id.button3,
        new int[]{R.id.button1, R.id.button3},
        null, ConstraintWidget.CHAIN_PACKED);

這個方法為我們創(chuàng)建了一個水平的 chain。這個方法需要5個參數(shù)陆爽。

第一個:頭部 view 的 id什往。
第二個:chain 里尾部 view 的 id。
第三個:int 數(shù)組慌闭,把頭部和尾部 view 的 id 放入 int 數(shù)組别威。
第四個:float 數(shù)組,如果我們需要權(quán)重的 chaining 的話它可以給我們權(quán)重贡必,否則的話為空兔港。
第五個:chaining 的風(fēng)格,類似 CHAIN_SPREAD仔拟。

現(xiàn)在如果我運行一下衫樊,我會得到下面的結(jié)果。


這不是我們需要的動作利花。如果你們還記得我清除了這些按鈕的 constraint科侈,這就是為什么這里的寬度和高度都為 0 的原因.如下所示,我需要給它們的寬度和高度賦值炒事。

applyConstraintSet.constrainWidth(R.id.button1,ConstraintSet.WRAP_CONTENT);
applyConstraintSet.constrainWidth(R.id.button2,ConstraintSet.WRAP_CONTENT);
applyConstraintSet.constrainWidth(R.id.button3,ConstraintSet.WRAP_CONTENT);

applyConstraintSet.constrainHeight(R.id.button1,ConstraintSet.WRAP_CONTENT);
applyConstraintSet.constrainHeight(R.id.button2,ConstraintSet.WRAP_CONTENT);
applyConstraintSet.constrainHeight(R.id.button3,ConstraintSet.WRAP_CONTENT);

現(xiàn)在再運行一次臀栈。

效果不錯,是時候向你們展示整段代碼了挠乳。

public void onApplyClick(View view) {
    TransitionManager.beginDelayedTransition(constraintLayout);

    applyConstraintSet.clear(R.id.button1);
    applyConstraintSet.clear(R.id.button2);
    applyConstraintSet.clear(R.id.button3);

    // button 1 left and top align to parent
    applyConstraintSet.connect(R.id.button1, ConstraintSet.LEFT, R.id.main, ConstraintSet.LEFT, 0);

    // button 3 right and top align to parent
    applyConstraintSet.connect(R.id.button3, ConstraintSet.RIGHT, R.id.main, ConstraintSet.RIGHT, 0);

    // bi-direction or Chaining between button 1 and button 2
    applyConstraintSet.connect(R.id.button2, ConstraintSet.LEFT, R.id.button1, ConstraintSet.RIGHT, 0);
    applyConstraintSet.connect(R.id.button1, ConstraintSet.RIGHT, R.id.button2, ConstraintSet.LEFT, 0);

    // bi-direction or Chaining between button 2 and button 3
    applyConstraintSet.connect(R.id.button2, ConstraintSet.RIGHT, R.id.button3, ConstraintSet.LEFT, 0);
    applyConstraintSet.connect(R.id.button3, ConstraintSet.LEFT, R.id.button2, ConstraintSet.RIGHT, 0);

    applyConstraintSet.createHorizontalChain(R.id.button1,
            R.id.button3,
            new int[]{R.id.button1, R.id.button3}, null, ConstraintWidget.CHAIN_PACKED);

    applyConstraintSet.constrainWidth(R.id.button1,ConstraintSet.WRAP_CONTENT);
    applyConstraintSet.constrainWidth(R.id.button2,ConstraintSet.WRAP_CONTENT);
    applyConstraintSet.constrainWidth(R.id.button3,ConstraintSet.WRAP_CONTENT);

    applyConstraintSet.constrainHeight(R.id.button1,ConstraintSet.WRAP_CONTENT);
    applyConstraintSet.constrainHeight(R.id.button2,ConstraintSet.WRAP_CONTENT);
    applyConstraintSet.constrainHeight(R.id.button3,ConstraintSet.WRAP_CONTENT);

    applyConstraintSet.applyTo(constraintLayout);
}

現(xiàn)在改變 chain 風(fēng)格权薯。

applyConstraintSet.createHorizontalChain(R.id.button1,
        R.id.button3,
        new int[]{R.id.button1, R.id.button3}, null, ConstraintWidget.CHAIN_SPREAD);

現(xiàn)在改變 chain 風(fēng)格。

applyConstraintSet.createHorizontalChain(R.id.button1,
        R.id.button3,
        new int[]{R.id.button1, R.id.button3}, null, ConstraintWidget.CHAIN_SPREAD_INSIDE);

現(xiàn)在我將向你們展示帶有偏差值的 CHAIN_PACKED睡扬。

applyConstraintSet.createHorizontalChain(R.id.button1,
        R.id.button3,
        new int[]{R.id.button1, R.id.button3}, null, ConstraintWidget.CHAIN_PACKED);

applyConstraintSet.setHorizontalBias(R.id.button1, .1f);

如上所示盟蚣,我使用了一個新方法 setHorizontalBias(),在這個方法里我填入了我們 chain 組的頭部和 float 類型的偏差值卖怜。

獎勵:

我將向你們展示 ConstraintSet 的另一個用法屎开,這個用法在 Android API 文檔里有提及到。所以如下所示马靠,首先我們先在同一個 ConstraintLayout 里應(yīng)用兩個不同的 ConstraintSet奄抽。

public class MainActivity extends AppCompatActivity {

    private ConstraintLayout constraintLayout;
    private ConstraintSet constraintSet1 = new ConstraintSet();
    private ConstraintSet constraintSet2 = new ConstraintSet();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        constraintLayout = (ConstraintLayout) findViewById(R.id.main);
        constraintSet1.clone(constraintLayout);
        constraintSet2.clone(this, R.layout.activity_main2);
    }

    public void onApplyClick(View view) {
        TransitionManager.beginDelayedTransition(constraintLayout);
        constraintSet2.applyTo(constraintLayout);
    }

    public void onResetClick(View view) {
        TransitionManager.beginDelayedTransition(constraintLayout);
        constraintSet1.applyTo(constraintLayout);
    }
}

activity_main 布局的 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.constraintanimation.MainActivity">


    <Button
        android:onClick="onApplyClick"
        app:layout_constraintHorizontal_weight="1"
        android:id="@+id/applyButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Apply"
        android:layout_marginLeft="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="16dp"
        app:layout_constraintRight_toLeftOf="@+id/resetButton"
        android:layout_marginRight="8dp"
        android:layout_marginEnd="8dp" />

    <Button
        android:onClick="onResetClick"
        app:layout_constraintHorizontal_weight="1"
        android:id="@+id/resetButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Reset"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="16dp"
        app:layout_constraintLeft_toRightOf="@+id/applyButton"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"

        />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="92dp"
        android:layout_height="92dp"
        app:srcCompat="@mipmap/ic_launcher"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.02"
        android:layout_marginEnd="8dp" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Hello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\n"
        android:layout_marginRight="8dp"
        android:lines="6"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginEnd="8dp"
        app:layout_constraintLeft_toRightOf="@+id/imageView"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="16dp" />

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginLeft="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="16dp"
        app:layout_constraintRight_toLeftOf="@+id/textView"
        android:layout_marginRight="8dp"
        app:layout_constraintHorizontal_bias="1.0"
        android:layout_marginEnd="8dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</android.support.constraint.ConstraintLayout>

activty_main2 布局的 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.constraintanimation.MainActivity">


    <Button
        android:onClick="onApplyClick"
        app:layout_constraintHorizontal_weight="1"
        android:id="@+id/applyButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Apply"
        android:layout_marginLeft="16dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="16dp"
        app:layout_constraintRight_toLeftOf="@+id/resetButton"
        android:layout_marginRight="8dp"
        android:layout_marginEnd="8dp" />

    <Button
        android:onClick="onResetClick"
        app:layout_constraintHorizontal_weight="1"
        android:id="@+id/resetButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Reset"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="16dp"
        app:layout_constraintLeft_toRightOf="@+id/applyButton"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"

        />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="353dp"
        android:layout_height="157dp"
        app:srcCompat="@mipmap/ic_launcher"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginEnd="8dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="8dp" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="352dp"
        android:layout_height="108dp"
        android:text="Hello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\nHello this is a simple demo. Thanks for reading and learning new things.\n"
        android:lines="6"
        android:layout_marginTop="12dp"
        app:layout_constraintTop_toBottomOf="@+id/imageView"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp" />

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginRight="16dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginEnd="16dp" />

    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Button"
        android:layout_marginRight="16dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginEnd="16dp"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toBottomOf="@+id/textView"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/applyButton" />

</android.support.constraint.ConstraintLayout>

哇哦,我們已經(jīng)完成了 ConstraitLayout 動畫甩鳄。剩下的最后一個主題是 ConstraintLayout 可視化[Design]編輯器 (這到底是什么)[第四部分]

好的各位逞度,是時候說再見了,希望你們都有一個很棒的周末妙啃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末第晰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茁瘦,老刑警劉巖品抽,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異甜熔,居然都是意外死亡圆恤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門腔稀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盆昙,“玉大人,你說我怎么就攤上這事焊虏〉玻” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵诵闭,是天一觀的道長炼团。 經(jīng)常有香客問我,道長疏尿,這世上最難降的妖魔是什么瘟芝? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮褥琐,結(jié)果婚禮上锌俱,老公的妹妹穿的比我還像新娘昌屉。我一直安慰自己伴栓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布常摧。 她就那樣靜靜地躺著磕洪,像睡著了一般锚赤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上褐鸥,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音赐稽,去河邊找鬼叫榕。 笑死,一個胖子當(dāng)著我的面吹牛姊舵,可吹牛的內(nèi)容都是我干的晰绎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼括丁,長吁一口氣:“原來是場噩夢啊……” “哼荞下!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤尖昏,失蹤者是張志新(化名)和其女友劉穎仰税,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抽诉,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡陨簇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了迹淌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片河绽。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唉窃,靈堂內(nèi)的尸體忽然破棺而出耙饰,到底是詐尸還是另有隱情,我是刑警寧澤纹份,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布苟跪,位于F島的核電站,受9級特大地震影響矮嫉,放射性物質(zhì)發(fā)生泄漏削咆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一蠢笋、第九天 我趴在偏房一處隱蔽的房頂上張望拨齐。 院中可真熱鬧,春花似錦昨寞、人聲如沸瞻惋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歼狼。三九已至,卻和暖如春享怀,著一層夾襖步出監(jiān)牢的瞬間羽峰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工添瓷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梅屉,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓鳞贷,卻偏偏與公主長得像坯汤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子搀愧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫惰聂、插件疆偿、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評論 4 62
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,510評論 25 707
  • 俄國詩人普希金有一首在全世界范圍內(nèi)流傳很廣的著名詩歌——《假如生活欺騙了你》: “假如生活欺騙了你 不要悲傷...
    上官飛鴻閱讀 396評論 7 17
  • 當(dāng)她們匆忙趕回學(xué)校時,趙璐偷錢包的事情已經(jīng)炸開了鍋搓幌。全校都知道了杆故,程英陪趙璐去了老班辦公室,平時去老班辦公室都是輕...
    沉清閱讀 244評論 0 1
  • 說點正事兒鼻种,今兒四娘要給你熬碗雞湯反番。 你視那渣男如珍寶,可是無論怎么努力都沒有回報叉钥,我知道罢缸,你是不肯放過自己的⊥抖樱或...
    風(fēng)的奇思和異想閱讀 466評論 0 0