新布局ConstraintLayout


引言

ConstraintLayout是Google在2016的Goodle I/O大會(huì)時(shí)提出的虏辫,目前的穩(wěn)定版本是1.0.2,它可以降低布局的嵌套層級(jí),提升頁(yè)面渲染。

參考文章:

1.幾種屬性介紹

1.2 相對(duì)位置

  • layout_constraintLeft_toLeftOf
    相對(duì)于依賴控件的左邊對(duì)當(dāng)前控件的左邊進(jìn)行約束設(shè)置
  • layout_constraintLeft_toRightOf
    相對(duì)于依賴控件的左邊對(duì)當(dāng)前控件的右邊進(jìn)行約束設(shè)置
  • layout_constraintRight_toLeftOf
    相對(duì)于依賴控件的右邊對(duì)當(dāng)前控件的左邊進(jìn)行約束設(shè)置
  • layout_constraintRight_toRightOf
    相對(duì)于依賴控件的右邊對(duì)當(dāng)前控件的右邊進(jìn)行約束設(shè)置
  • layout_constraintTop_toTopOf
    相對(duì)于依賴控件的頂部對(duì)當(dāng)前控件的頂部進(jìn)行約束設(shè)置
  • layout_constraintTop_toBottomOf
    相對(duì)于依賴控件的底部對(duì)當(dāng)前控件的頂部進(jìn)行約束設(shè)置
  • layout_constraintBottom_toTopOf
    相對(duì)于依賴控件的頂部部對(duì)當(dāng)前控件的底部進(jìn)行約束設(shè)置
  • layout_constraintBottom_toBottomOf
    相對(duì)于依賴控件的底部部對(duì)當(dāng)前控件的底部進(jìn)行約束設(shè)置
  • layout_constraintBaseline_toBaselineOf
    設(shè)置兩個(gè)空間之間的 文字相對(duì)于baseline對(duì)齊
  • layout_constraintStart_toEndOf
  • layout_constraintStart_toStartOf
  • layout_constraintEnd_toStartOf
  • layout_constraintEnd_toEndOf

效果圖:


布局文件

<?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:id="@+id/activity_relative_position"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/btn_A"
        android:text="A"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        style="@style/Constraint_style"/>
    <Button
        style="@style/Constraint_style"
        android:text="在A上方购城,與A居中對(duì)齊"
        app:layout_constraintLeft_toLeftOf="@id/btn_A"
        app:layout_constraintRight_toRightOf="@id/btn_A"
        android:layout_marginBottom="40dp"
        app:layout_constraintBottom_toTopOf="@id/btn_A"/>
    <Button
        style="@style/Constraint_style"
        android:text="平居中對(duì)齊"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:layout_marginLeft="10dp"
        app:layout_constraintLeft_toRightOf="@id/btn_A"
        app:layout_constraintTop_toTopOf="@id/btn_A"
        app:layout_constraintBottom_toBottomOf="@id/btn_A"/>
    <Button
        style="@style/Constraint_style"
        android:text="在A下方,與A左對(duì)齊"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="@id/btn_A"
        app:layout_constraintTop_toBottomOf="@id/btn_A"
        android:layout_marginTop="100dp"/>
    <Button
        style="@style/Constraint_style"
        android:text="在A下方虐译,與A右對(duì)齊"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toRightOf="@id/btn_A"
        app:layout_constraintTop_toBottomOf="@id/btn_A"
        android:layout_marginTop="25dp"/>
    <Button
        style="@style/Constraint_style"
        android:text="BASELINE對(duì)齊"
        android:layout_width="wrap_content"
        android:layout_height="80dp"
        android:gravity="bottom"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="10dp"
        app:layout_constraintBaseline_toBaselineOf="@id/btn_A"/>


</android.support.constraint.ConstraintLayout>

1.3 邊距

在ConstrainLayout中瘪板,控件除了可以設(shè)置普通的邊距屬性,還可以設(shè)置當(dāng)空間依賴的控件GONE之后的邊距屬性漆诽。下面是依賴控件GONE之后的邊距屬性:

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom

需求:B控件依賴A侮攀,A距離父容器左邊20dp锣枝,B在A右邊,距離A為20dp兰英。需求當(dāng)A設(shè)置為GONE之后撇叁,B距離父容器左邊60dp。

A在gone之前的效果圖:


<?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:id="@+id/activity_margin"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        style="@style/Constraint_style"
        android:id="@+id/btn_a"
        android:text="A"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="100dp"
        />

    <Button
        style="@style/Constraint_style"
        android:text="B"
        android:textAllCaps="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@id/btn_a"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginLeft="20dp"
        app:layout_goneMarginLeft="60dp"
        android:layout_marginTop="100dp"
        />

</android.support.constraint.ConstraintLayout>

A在gone之后的效果圖:


1.3 偏移

控件設(shè)置居中(包括水平居中箭昵、垂直居中税朴、水平垂直居中)屬性之后,通過(guò)偏移屬性可以設(shè)置染空間更偏向于依賴控件的某一方家制,偏移值設(shè)置為0-1之間的值。

  • layout_constraintHorizontal_bias
    水平偏移
  • layout_constraintVertical_bias
    垂直偏移

效果圖:


布局文件:

<?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:id="@+id/activity_margin"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        style="@style/Constraint_style"
        android:id="@+id/btn_a"
        android:text="水平偏移30%"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.3"
        />

    <Button
        style="@style/Constraint_style"
        android:text="垂直偏移30%"
        android:textAllCaps="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.3"
        />
    <Button
        style="@style/Constraint_style"
        android:text="水平居中偏移70%"
        android:textAllCaps="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_bias="0.7"
        app:layout_constraintVertical_bias="0.7"
        />


</android.support.constraint.ConstraintLayout>

1.4可見(jiàn)性

約束布局的可見(jiàn)性屬性:

  • 當(dāng)控件設(shè)為GONE時(shí)泡一,被認(rèn)為尺寸為0颤殴,可以理解為布局上的一個(gè)點(diǎn);
  • 當(dāng)GONE的控件對(duì)其他控件有約束鼻忠,則約束保留并生效涵但,但所有的邊距會(huì)清0.

1.5 尺寸

  • 設(shè)置固定尺寸
  • 使用wrap_content,根據(jù)內(nèi)容計(jì)算合適大小
  • match_parent:填滿父布局帖蔓,此時(shí)設(shè)置的約束都不生效了矮瘟。
  • 設(shè)置0dp,相當(dāng)于MATCH_CONSTRAINT屬性塑娇,基于約束最終確定大小澈侠。

MATH_CONSTRAINT

  • layout_constraintWidth_min和layout_constraintHeight_min:設(shè)置最小值
  • layout_constraintWidth_max和layout_constraintHeight_max:設(shè)置最大值
  • layout_constraintWidth_percent和layout_constraintHeight_percent:設(shè)置控件相對(duì)于父容器的百分比大小。使用之前需要先設(shè)置為百分比模式埋酬,然后設(shè)置寬高值為0-1之間哨啃。
    設(shè)置為百分比模式的屬性:(ConstraintLayout在1.1.x以上才可以用)
app:layout_constraintWidth_default="percent" 
app:layout_constraintHeight_default="percent" 

下面是具體示例:


布局文件:

<?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:id="@+id/activity_dimen"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_1"
        android:text="minWidth設(shè)置為200dp"
        android:textAllCaps="false"
        style="@style/Constraint_style"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:minWidth="200dp"
        />

    <Button
        android:id="@+id/btn_2"
        android:text="設(shè)置為MATCH_CONSTRAINT"
        style="@style/Constraint_style"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        app:layout_constraintTop_toBottomOf="@id/btn_1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

    <Button
        android:id="@+id/btn_3"
        android:textAllCaps="false"
        android:text="layout_constrainedWidth開啟"
        style="@style/Constraint_style"
        android:layout_marginTop="10dp"

        app:layout_constraintTop_toBottomOf="@id/btn_2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constrainedWidth="true"
        app:layout_constraintWidth_min="300dp"
        />
    <Button
        android:id="@+id/btn_4"
        android:textAllCaps="false"
        android:text="layout_constrainedWidth關(guān)閉"
        style="@style/Constraint_style"
        android:layout_marginTop="10dp"

        app:layout_constraintTop_toBottomOf="@id/btn_3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintWidth_min="300dp"
        />
    <Button
        android:id="@+id/btn_5"
        android:textAllCaps="false"
        android:text="寬50%高30%布局"
        style="@style/Constraint_style"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="10dp"
        app:layout_constraintTop_toBottomOf="@id/btn_4"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintWidth_percent="0.5"
        app:layout_constraintHeight_percent="0.3"
        />
</android.support.constraint.ConstraintLayout>

1.6 比例

控件可以定義自身寬高之間的比例,前提條件是至少有一個(gè)尺寸設(shè)置為0dp写妥,然后通過(guò)layout_constraintDimentionRatio屬性設(shè)置寬高比拳球。設(shè)置方式有以下幾種:

  • 直接設(shè)置一個(gè)float值,表示寬高
  • 以“width:height”形式設(shè)置
  • 通過(guò)設(shè)置前綴W或H珍特,指定一遍相對(duì)于另一邊的尺寸祝峻,如“H,16:9”,高比寬為16:9

如果寬高設(shè)置為odp扎筒,也可以用ratio設(shè)置莱找,這種情況下空間會(huì)滿足比例約束的條件下,盡可能填滿父布局砸琅。

下面是具體示例:


布局文件:

<?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:id="@+id/activity_dimen"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_1"
        android:text="寬高比設(shè)置為2:1"
        style="@style/Constraint_style"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

    <Button
        android:id="@+id/btn_2"
        android:text="寬高都設(shè)置為0dp,高寬比為16:9"
        style="@style/Constraint_style"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintDimensionRatio="H,16:9"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/btn_1"
        android:textAllCaps="false"
        />

</android.support.constraint.ConstraintLayout>

1.7 鏈

鏈這個(gè)概念是約束布局新提出的宋距,它提供了在一個(gè)維度(水平或者垂直),管理一組空間的方式症脂。

2. Guideline

用于布局輔助谚赎,不在設(shè)備上顯示淫僻。有垂直和水平兩個(gè)方向(android:orientation=“vertical/horizontal”)

  • 垂直:寬度為0,高度等于父容器
  • 水平:高度為0壶唤,寬度等于父容器

有三種放置Guideline的方式:

  • 給定距離左邊或頂部一個(gè)固定距離(layout_constraintGuide_begin)
  • 給定距離右邊或底部一個(gè)固定距離(layout_constraintGuide_end)
  • 給定寬高一個(gè)百分比距離(layout_constraintGuide_percent)

具體示例:


布局文件:

<?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:id="@+id/activity_dimen"
    android:padding="16dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--垂直Guideline-->
    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.5"
        android:orientation="vertical"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        />
    <Button
        android:id="@+id/btn_1"
        android:textAllCaps="false"
        android:text="Guideline左邊"
        style="@style/Constraint_style"
        app:layout_constraintRight_toLeftOf="@id/guideline"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        />


    <Button
        android:id="@+id/btn_2"
        android:textAllCaps="false"
        android:text="Guideline右邊"
        style="@style/Constraint_style"
        app:layout_constraintLeft_toRightOf="@id/guideline"
        android:layout_marginTop="16dp"
        app:layout_constraintTop_toTopOf="parent"
        />

    <!--水平Guideline-->
    <android.support.constraint.Guideline
        android:id="@+id/h_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintGuide_begin="200dp"
        />
    <Button
        android:id="@+id/btn_3"
        android:textAllCaps="false"
        android:text="Guideline上面"
        style="@style/Constraint_style"
        app:layout_constraintBottom_toBottomOf="@id/h_guideline"
        app:layout_constraintLeft_toLeftOf="parent"
        />
     <Button
        android:id="@+id/btn_4"
        android:text="Guideline下面"
        style="@style/Constraint_style"
        app:layout_constraintTop_toTopOf="@id/h_guideline"
        app:layout_constraintLeft_toLeftOf="parent"
        />

</android.support.constraint.ConstraintLayout>

3. ConstraintSet

通過(guò)ConstraintSet雳灵,允許在代碼中進(jìn)行約束設(shè)置,進(jìn)行布局變換闸盔。(API 19及以上支持transmition動(dòng)畫)
創(chuàng)建ConstraintSet對(duì)象的幾種方式:

  • 手動(dòng)
c = new ConstraintSet(); 
c.connect(....);
  • 通過(guò)一個(gè)R.layout.xxx對(duì)象
c.clone(context, R.layout.layout1);
  • 通過(guò)一個(gè)ConstraintLayout對(duì)象
c.clone(clayout);

布局變化開啟平滑動(dòng)畫的方式:

TransitionManager.beginDelayedTransition(constraintLayout);

其中參數(shù)constraintLayout表示動(dòng)畫作用的約束布局對(duì)象悯辙。
更多關(guān)于ConstraintSet的知識(shí)可以參考這篇文章

4.實(shí)踐

效果圖:



要求:圖片寬高比16:9迎吵,圖片寬度固定110dp躲撰。

分析:寬高比16:9,需要比例布局击费;其他都是一些位置關(guān)系拢蛋,用約束布局相對(duì)位置的一些約束可以實(shí)現(xiàn)。

布局文件:

<?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:layout_width="match_parent"
                                             android:layout_height="wrap_content"
                                             android:paddingLeft="15dp"
                                             android:paddingTop="12dp">

    <ImageView
        android:id="@+id/iv_course"
        android:layout_width="110dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        android:src="@mipmap/head"
        app:layout_constraintDimensionRatio="16:9"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_course_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="15dp"
        android:ellipsize="end"
        android:maxLines="2"
        android:textColor="#333333"
        android:textSize="15sp"
        app:layout_constraintLeft_toRightOf="@id/iv_course"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/iv_course"
        android:text="六年級(jí)單元過(guò)關(guān)檢測(cè)六年級(jí)單元過(guò)關(guān)檢測(cè)六年級(jí)單元過(guò)關(guān)檢測(cè)" />


    <TextView
        android:id="@+id/tv_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="15dp"
        android:layout_marginTop="5dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:textColor="#666666"
        android:textSize="12sp"
        app:layout_constraintLeft_toLeftOf="@id/tv_course_name"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_course_name"
        android:text="內(nèi)容內(nèi)容內(nèi)容內(nèi)容內(nèi)容" />

    <TextView
        android:id="@+id/tv_current_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:maxLines="1"
        android:textColor="#f6454a"
        android:textSize="15sp"
        app:layout_constraintLeft_toLeftOf="@id/tv_course_name"
        app:layout_constraintTop_toBottomOf="@id/tv_content"
        android:text="¥ 480" />

    <TextView
        android:id="@+id/tv_origin_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:maxLines="1"
        android:textColor="#999999"
        android:textSize="12sp"
        app:layout_constraintBottom_toBottomOf="@id/tv_current_price"
        app:layout_constraintLeft_toRightOf="@id/tv_current_price"
        android:text="¥ 1480" />

</android.support.constraint.ConstraintLayout>

針對(duì)上面的效果
要求:圖片寬度占整個(gè)布局30%蔫巩,寬高比16:9谆棱。
分析:看到30%,首先考慮的是百分比布局圆仔,但是圖片右邊的view較多垃瞧,每個(gè)都是設(shè)置一邊百分比,實(shí)在是麻煩坪郭。因此个从,可以考慮使用Guideline,設(shè)置Guideline垂直截粗,并距離父容器左邊30%的距離信姓,之后布局通過(guò)Guideline設(shè)置約束即可。
布局文件:

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="15dp"
    android:paddingTop="12dp">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ImageView
        android:id="@+id/iv_course"
        android:layout_width="110dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        android:src="@mipmap/test"
        app:layout_constraintDimensionRatio="16:9"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="@id/guideline"
        app:layout_constraintTop_toTopOf="parent"
 />
...

要求:在之前基礎(chǔ)上绸罗,底部加一根橫線用于分隔意推,要求線與上面最近的控件距離是15dp。
分析:由于文字內(nèi)容是可變的珊蟀,當(dāng)文字內(nèi)容多的時(shí)候菊值,線可能距離文字近;若文字不多育灸,線也可能距離圖片近腻窒。這個(gè)時(shí)候,基于當(dāng)前最新1.0.2穩(wěn)定版本的約束布局已經(jīng)不能滿足我們實(shí)現(xiàn)一層布局了磅崭,還是需要將圖片和文字整體放入一個(gè)布局容器中儿子,然后橫線依賴這個(gè)布局容器設(shè)置約束實(shí)現(xiàn),嵌套好像在所難免了砸喻。然而柔逼,當(dāng)約束布局1.1.0穩(wěn)定版本發(fā)布時(shí)蒋譬,這問(wèn)題也可以得到解決。我們先來(lái)看看在1.1.0上是怎么實(shí)現(xiàn)的:

<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="15dp"
    android:paddingTop="12dp">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:layout_editor_absoluteY="0dp"
        tools:layout_editor_absoluteX="104dp"/>

    ...
    <android.support.constraint.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="iv_course, tv_origin_price"
        tools:layout_editor_absoluteY="79dp"
        tools:layout_editor_absoluteX="0dp"/>

    <View
        android:layout_width="329dp"
        android:layout_height="1dp"
        android:background="#d8d8d8"
        android:layout_marginTop="12dp"
        app:layout_constraintTop_toBottomOf="@+id/barrier"
        />
</android.support.constraint.ConstraintLayout>

具體關(guān)于Barrier的用法我們可以繼續(xù)往下看愉适。

5. ConstraintLayout的性能

  • 相對(duì)于傳統(tǒng)布局犯助,ConstraintLayout的布局層級(jí)減少了
  • 具體一些性能的對(duì)比,如渲染速度和計(jì)算次數(shù)等维咸,可以參考這篇文章剂买,< 了解使用 ConstraintLayout 的性能優(yōu)勢(shì)>,通過(guò)結(jié)論可知使用了ConstraintLayout癌蓖,布局計(jì)算次數(shù)降低了瞬哼,渲染速度也相應(yīng)提升了。

6. 布局編輯器

Android studio 2.2之前的布局編輯器不夠完善费坊,部分約束不能設(shè)置倒槐,因此推薦使用版本為2.3或者更高的Android studio。關(guān)于布局編輯器可以參考下面這兩邊文章:

7. ConstraintLayout使用小結(jié)

7.1 margin只能設(shè)置正值或者0,負(fù)值無(wú)效

我們之前實(shí)現(xiàn)重疊布局時(shí)两残,或通過(guò)設(shè)置負(fù)的margin值實(shí)現(xiàn)永毅,但是在約束布局中,負(fù)的margin值不會(huì)生效人弓,只能設(shè)置0或者大于0 的值沼死,小于0也當(dāng)做0處理

7.2 鏈的書寫方式注意

一般布局我們都是遵守先定義,后使用原則崔赌,但是約束布局實(shí)現(xiàn)鏈時(shí)意蛀,這個(gè)原則就遵守不了了,這個(gè)時(shí)候如果還是按照常規(guī)的@id/btn_2的方式指定一來(lái)控件(這個(gè)控件在當(dāng)前控件之后聲明)健芭,就會(huì)報(bào)Error:(23, 46) No resource found that matches the given name錯(cuò)誤县钥。解決方案其實(shí)很簡(jiǎn)單,只需修改指定方式如下:@+id/btn_2即可慈迈。

7.3 ConstraintSet動(dòng)畫Api支持等級(jí)

在代碼中設(shè)置控件約束若贮,可以通過(guò)ConstraintSet實(shí)現(xiàn)。約束變了之后痒留,布局肯定會(huì)跟著變谴麦。TransitionManager.beginDelayedTransition提供了平滑動(dòng)畫變換布局的能力,但是只支持Api 19及以上的版本伸头。

7.4 自定義GuideLine

對(duì)Guideline設(shè)置相對(duì)位置屬性時(shí)不生效的匾效,因此當(dāng)我們想要一個(gè)相對(duì)于某個(gè)View的Guideline時(shí),約束布局時(shí)不能滿足我們的要求的恤磷,看Guideline源碼:

public class Guideline extends View {
    public Guideline(Context context) {
        super(context);
        super.setVisibility(8);
    }
    ...    
}

發(fā)現(xiàn)Guideline是一個(gè)不可見(jiàn)的view面哼,那么我們可以布局時(shí)放置一個(gè)不可見(jiàn)的view來(lái)作為Guideline的替代品野宜,實(shí)現(xiàn)一些特殊布局要求。如布局重疊:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"

    >
    <Button
        android:id="@+id/btn_a"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:text="B"
        android:textSize="20sp"
        android:textColor="@color/white"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#fd368d"
        tools:layout_editor_absoluteY="0dp"/>
    <View
        android:id="@+id/view"
        android:layout_height="0dp"
        android:layout_width="0dp"
        app:layout_constraintBottom_toBottomOf="@id/btn_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginBottom="40dp"/>
    <Button
        android:text="A"
        android:layout_height="200dp"
        android:layout_width="wrap_content"
        android:textColor="@color/white"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="@color/colorPrimary"
        app:layout_constraintTop_toBottomOf="@id/view"/>

</android.support.constraint.ConstraintLayout>

效果圖:



這種方式可以彌補(bǔ)margin不能設(shè)置為負(fù)值的不足

7.5 區(qū)分0dp精绎、match_parent和MATCH_CONSTRAINT

  • 0dp等價(jià)于MATCH_CONSTRAINT速缨,對(duì)控件設(shè)置其他尺寸相關(guān)約束會(huì)生效,如app:layout_constraintWidth_min等約束
  • match_parent,填充滿父布局代乃,之后設(shè)置約束屬性無(wú)效

7.6 使用布局編輯器多出了一些屬性

layout_optimizationLevel
layout_editor_absoluteX
layout_editor_absoluteY
layout_constraintBaseline_creator
layout_constraintTop_creator
layout_constraintRight_creator
layout_constraintLeft_creator
layout_constraintBottom_creator

這幾個(gè)屬性是 UI 編輯器所使用的旬牲,用了輔助拖拽布局的,在實(shí)際使用過(guò)程中搁吓,可以不用關(guān)心這些屬性原茅。

8. 1.1.0-beta3的新特性

  • Barrier
    Barrier是一個(gè)虛擬的輔助控件,它可以阻止一個(gè)或者多個(gè)控件越過(guò)自己堕仔,就像一個(gè)屏障一樣擂橘,當(dāng)某個(gè)控件要越過(guò)自己的時(shí)候,Barrier會(huì)自動(dòng)移動(dòng)摩骨,避免自己被覆蓋通贞。
  • Group
    Goup幫助你對(duì)一組控件進(jìn)行設(shè)置,最常見(jiàn)的情況就是控制一組控件的visibility恼五,你只需把控件的id添加到group昌罩,就能同時(shí)對(duì)立面的所有控件進(jìn)行操作。
  • Circular positioning
    可以相對(duì)另一個(gè)控件灾馒,以角度和距離定義當(dāng)前控件的位置茎用,即提供了在圓上定義控件位置的能力,如圖所示:


  • Placeholder
    Placeholder顧名思義睬罗,就是用來(lái)一個(gè)占位的東西轨功,它可以把自己的內(nèi)容設(shè)置為ConstraintLayout內(nèi)的其他view,因此它用來(lái)寫布局的模板容达,也可以用來(lái)動(dòng)態(tài)修改UI的內(nèi)容古涧。
  • 百分比布局
    允許設(shè)置控件占據(jù)可用空間的百分比,大大增加布局靈活度和適配性董饰。

具體文章參考Constraint Layout 1.1.x帶來(lái)了哪些新東西蒿褂?

9. ConstraintLayout的優(yōu)勢(shì)

  • 布局高效
  • 輕松對(duì)應(yīng)復(fù)雜布局
  • 嵌套層級(jí)少
  • 適配性好
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市卒暂,隨后出現(xiàn)的幾起案子啄栓,更是在濱河造成了極大的恐慌,老刑警劉巖也祠,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昙楚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡诈嘿,警方通過(guò)查閱死者的電腦和手機(jī)堪旧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門削葱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人淳梦,你說(shuō)我怎么就攤上這事析砸。” “怎么了爆袍?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵首繁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我陨囊,道長(zhǎng)弦疮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任蜘醋,我火速辦了婚禮胁塞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘压语。我一直安慰自己啸罢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布胎食。 她就那樣靜靜地躺著伺糠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪斥季。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天累驮,我揣著相機(jī)與錄音酣倾,去河邊找鬼。 笑死谤专,一個(gè)胖子當(dāng)著我的面吹牛躁锡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播置侍,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼映之,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蜡坊?” 一聲冷哼從身側(cè)響起杠输,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秕衙,沒(méi)想到半個(gè)月后蠢甲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡据忘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年鹦牛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搞糕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡曼追,死狀恐怖窍仰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情礼殊,我是刑警寧澤驹吮,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站膏燕,受9級(jí)特大地震影響钥屈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坝辫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一篷就、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧近忙,春花似錦竭业、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至锯玛,卻和暖如春咐柜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背攘残。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工拙友, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歼郭。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓遗契,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親病曾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牍蜂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

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