×

ConstraintLayout 使用

96
龙衣袭 Excellent
2017.09.25 21:16* 字数 320

学习来源:鸿洋大神的公众号 拒绝拖拽 使用ConstraintLayout优化你的布局吧

1、作用

ConstraintLayout 允许您构建复杂的布局,而不必嵌套 View 和 ViewGroup 元素,使用 ConstraintLayout 布局能够减少 UI 的绘制,优化性能。

2、使用

image.png

要实现以上布局想必需要嵌套不少布局吧,现在告诉你使用一个ConstrainLayou就够了

  • Banner 页的布局
    这里只采用了一个 TextView 去做展示,实际中只需要用用相应的Banner库或者自己写的Banner界面去填充即可。布局如下:
<?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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#11ff0000"
    android:id="@+id/constraintLayout">

    <TextView
        android:id="@+id/banner"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#765"
        android:gravity="center"
        android:text="Banner"
        app:layout_constraintDimensionRatio="H,16:9"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />
    ....
</android.support.constraint.ConstraintLayout>
  • 新的API
 android:layout_width="0dp"                       // 需要设置为0dp,相当于match_parent
 android:layout_height="0dp"                      // 需要设置为0dp,相当于match_parent
 app:layout_constraintLeft_toLeftOf="parent"      // 在父布局的左边
 app:layout_constraintRight_toRightOf="parent"    // 在父布局的右边
 app:layout_constraintDimensionRatio="H,16:9"     // 宽高比,需要填以上4个操作才有效果
//  app:layout_constraintDimensionRatio="W,16:6"
//  app:layout_constraintDimensionRatio="H,16:6"
  • 新闻item
<?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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#11ff0000"
    android:id="@+id/constraintLayout">

    .....

    <ImageView
        android:id="@+id/img_guitar"
        android:layout_width="140dp"
        android:layout_height="86dp"
        android:src="@drawable/guitar"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="12dp"
        app:layout_constraintTop_toBottomOf="@+id/banner"
        app:layout_constraintLeft_toLeftOf="parent"
        />
    <TextView
        android:id="@+id/tv2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="12dp"
        android:text="马云:一年交税170多亿马云:一年交税170多亿马云:一年交税170多亿"
        android:textColor="#000000"
        android:textSize="16dp"
        app:layout_constraintLeft_toRightOf="@+id/img_guitar"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@+id/img_guitar"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="12dp"
        android:text="8分钟前"
        android:textColor="#333"
        android:textSize="12dp"
        app:layout_constraintLeft_toRightOf="@+id/img_guitar"
        app:layout_constraintBottom_toBottomOf="@+id/img_guitar"
        />
    ......

</android.support.constraint.ConstraintLayout>
  • 新的API
图片在Banner的下方,图片在父布局的左边
app:layout_constraintTop_toBottomOf="@+id/banner"    // id是Top,要显示的是Bottom
app:layout_constraintLeft_toLeftOf="parent"

文字在banner下方,在图片左边满屏,顶部和图片对齐
 app:layout_constraintLeft_toRightOf="@+id/img_guitar"    // img_guitar右边是文字
 app:layout_constraintRight_toRightOf="parent"    // 需要设置
 layout_width="0dp",相当于match_parent
 app:layout_constraintTop_toTopOf="@+id/img_guitar"    // 顶部对齐

时间在图片的右边,与图片底部对齐
 app:layout_constraintLeft_toRightOf="@+id/img_guitar"
 app:layout_constraintBottom_toBottomOf="@+id/img_guitar"
  • 按钮
<Button
        android:id="@+id/btn1"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="12dp"
        android:text="你好"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/img_guitar"
        />
    <Button
        android:id="@+id/btn2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="12dp"
        android:text="你好"
        app:layout_constraintLeft_toRightOf="@+id/btn1"
        app:layout_constraintTop_toBottomOf="@+id/img_guitar"
        app:layout_constraintRight_toRightOf="parent"
        />
  • 按钮的实现没啥新的API,之前页使用过了,主要注意的就是需要修改 layout_width="0dp" ,否则不能填满剩余的父布局

  • 底部的三个 Tab 实现

<TextView
        android:id="@+id/tab1"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#f67"
        android:gravity="center"
        android:text="Tab1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/tab2"
        app:layout_constraintHorizontal_weight="1"
        />
    <TextView
        android:id="@+id/tab2"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#A67"
        android:gravity="center"
        android:text="Tab2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/tab1"
        app:layout_constraintRight_toLeftOf="@+id/tab3"
        app:layout_constraintHorizontal_weight="2"
        />
    <TextView
        android:id="@+id/tab3"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#767"
        android:gravity="center"
        android:text="Tab3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/tab2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_weight="1"
        />
  • 主要思想就是两两互相约束
    app:layout_constraintHorizontal_weight="1"这个属性是设置占比,和LinearLayoutlayout_weight相像

  • 悬浮按钮的实现

<android.support.constraint.Guideline
        android:id="@+id/guideline_h"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.8"        // 横向距离顶部80%
        />
    <android.support.constraint.Guideline
        android:id="@+id/guideline_w"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.8"        // 纵向距离顶部80%
        />
    <android.support.design.widget.FloatingActionButton
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintLeft_toRightOf="@id/guideline_w"    
        app:layout_constraintTop_toBottomOf="@id/guideline_h"   // 悬浮按钮就在二者的交点展示
        />
  • 新的API
android.support.constraint.Guideline该类比较简单,主要用于辅助布局,即类似为辅助线,横向的、纵向的。该布局是不会显示到界面上的。

android:orientation取值为"vertical"和"horizontal".
除此以外,还差个属性,决定该辅助线的位置:
layout_constraintGuide_begin
layout_constraintGuide_end
layout_constraintGuide_percent

可以通过上面3个属性其中之一来确定属性值位置。

begin=30dp,即可认为距离顶部30dp的地方有个辅助线,根据orientation来决定是横向还是纵向。
end=30dp,即为距离底部。 percent=0.8即为距离顶部80

在这里还可以通过这两个属性去实现这个悬浮按钮
layout_constraintHorizontal_bias="0.9"
layout_constraintVertical_bias="0.9"
即设置上下两侧间隙比例分别为90%与10%

 <android.support.design.widget.FloatingActionButton
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintHorizontal_bias="0.9"
        app:layout_constraintVertical_bias="0.9"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

全部代码

<?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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#11ff0000"
    android:id="@+id/constraintLayout">

    <TextView
        android:id="@+id/banner"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="#765"
        android:gravity="center"
        android:text="Banner"
        app:layout_constraintDimensionRatio="H,16:9"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

    <ImageView
        android:id="@+id/img_guitar"
        android:layout_width="140dp"
        android:layout_height="86dp"
        android:src="@drawable/guitar"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="12dp"
        app:layout_constraintTop_toBottomOf="@+id/banner"
        app:layout_constraintLeft_toLeftOf="parent"
        />
    <TextView
        android:id="@+id/tv2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="12dp"
        android:text="马云:一年交税170多亿马云:一年交税170多亿马云:一年交税170多亿"
        android:textColor="#000000"
        android:textSize="16dp"
        app:layout_constraintLeft_toRightOf="@+id/img_guitar"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@+id/img_guitar"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="12dp"
        android:text="8分钟前"
        android:textColor="#333"
        android:textSize="12dp"
        app:layout_constraintLeft_toRightOf="@+id/img_guitar"
        app:layout_constraintBottom_toBottomOf="@+id/img_guitar"
        />
    <Button
        android:id="@+id/btn1"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="12dp"
        android:text="你好"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/img_guitar"
        />
    <Button
        android:id="@+id/btn2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:layout_marginLeft="12dp"
        android:text="你好"
        app:layout_constraintLeft_toRightOf="@+id/btn1"
        app:layout_constraintTop_toBottomOf="@+id/img_guitar"
        app:layout_constraintRight_toRightOf="parent"
        />
    <TextView
        android:id="@+id/tab1"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#f67"
        android:gravity="center"
        android:text="Tab1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/tab2"
        app:layout_constraintHorizontal_weight="1"
        />
    <TextView
        android:id="@+id/tab2"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#A67"
        android:gravity="center"
        android:text="Tab2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/tab1"
        app:layout_constraintRight_toLeftOf="@+id/tab3"
        app:layout_constraintHorizontal_weight="2"
        />
    <TextView
        android:id="@+id/tab3"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:background="#767"
        android:gravity="center"
        android:text="Tab3"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/tab2"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintHorizontal_weight="1"
        />
    <android.support.constraint.Guideline
        android:id="@+id/guideline_h"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.8"
        />
    <android.support.constraint.Guideline
        android:id="@+id/guideline_w"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.8"
        />
    <!--<android.support.design.widget.FloatingActionButton-->
        <!--android:layout_width="60dp"-->
        <!--android:layout_height="60dp"-->
        <!--app:layout_constraintHorizontal_bias="0.9"-->
        <!--app:layout_constraintVertical_bias="0.9"-->
        <!--app:layout_constraintBottom_toBottomOf="parent"-->
        <!--app:layout_constraintLeft_toLeftOf="parent"-->
        <!--app:layout_constraintRight_toRightOf="parent"-->
        <!--app:layout_constraintTop_toTopOf="parent"-->
        <!--/>-->

    <android.support.design.widget.FloatingActionButton
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintLeft_toRightOf="@id/guideline_w"
        app:layout_constraintTop_toBottomOf="@id/guideline_h"/>
</android.support.constraint.ConstraintLayout>
开发
Web note ad 1