学习使用ConstraintLayout布局实战

版权声明:本文为博主原创文章,未经博主容许不得转载。 https://blog.csdn.net/dingshuhong_/article/details/80195498

1、概述

ConstraintLayout 布局已经出来有一两年了,最早开始由于视图化的布局,因此一直没有使用过,最近浏览其余博客的时候,屡次看到ConstraintLayout 是官方推荐使用的布局,并且相对于其余的四大布局,有不少性能方面的优点。因此有必要学习和使用一下这个布局。下面开始吧!
引入依赖(已经到1.1版本了,是应该多尝试使用这个布局了)android

implementation 'com.android.support.constraint:constraint-layout:1.1.0'

2、效果展现

不喜欢视图化布局,其实也能够手写属性来布局。下面展现下我看hongyang大神博客时手写布局的效果。
布局效果
下面是布局xml代码:markdown

<?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="match_parent">

    <ImageView  android:id="@+id/img_banner" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="15dp" android:background="@color/colorPrimaryDark" app:layout_constraintDimensionRatio="H,16:9" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" />

    <ImageView  android:id="@+id/img_left" android:layout_width="146dp" android:layout_height="86dp" android:layout_marginBottom="10dp" android:layout_marginLeft="12dp" android:layout_marginTop="10dp" android:background="@color/colorPrimary" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@+id/img_banner" />

    <TextView  android:id="@+id/txt_content" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="马云:一年交税170多亿马云:一年交税170多亿马云:一年交税170多亿" app:layout_constraintLeft_toRightOf="@+id/img_left" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="@+id/img_left" />

    <TextView  android:layout_width="0dp" android:layout_height="wrap_content" android:text="8分钟前" app:layout_constraintBottom_toBottomOf="@+id/img_left" app:layout_constraintLeft_toLeftOf="@+id/txt_content" />

    <TextView  android:layout_width="60dp" android:layout_height="60dp" android:background="@color/colorPrimary" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_bias="0.9" app:layout_constraintVertical_bias="0.9"/>
    <TextView  android:id="@+id/tab1" android:layout_width="0dp" android:layout_height="40dp" android:background="@android:color/darker_gray" android:gravity="center" android:text="tab1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/tab2" />

    <TextView  android:id="@+id/tab2" android:layout_width="0dp" android:layout_height="40dp" android:background="@android:color/holo_green_light" android:gravity="center" android:text="tab1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintLeft_toRightOf="@+id/tab1" app:layout_constraintRight_toLeftOf="@+id/tab3" />

    <TextView  android:id="@+id/tab3" android:layout_width="0dp" android:layout_height="40dp" android:background="@android:color/holo_red_light" android:gravity="center" android:text="tab1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintLeft_toRightOf="@+id/tab2" app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

3、属性介绍

结合这个上面这个布局介绍下ConstraintLayout的属性吧app

一、相对位置(Relative positioning)

在横向和纵向上添加约束关系来固定控件位置,官方一共提供给咱们这些相对约束属性:这里写图片描述
下面咱们对比下效果
没有添加约束布局

<?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:layout_width="match_parent" android:layout_height="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮01"/>

    <Button  android:id="@+id/btn_02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮2"/>

</android.support.constraint.ConstraintLayout>

没有添加按钮2在按钮1的右边的约束性能

<?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:layout_width="match_parent" android:layout_height="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮01"/>

    <Button  android:id="@+id/btn_02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮2" app:layout_constraintLeft_toRightOf="@+id/btn_01"/>

</android.support.constraint.ConstraintLayout>

没有添加约束没有添加按钮2在按钮1的右边的约束
仅仅添加了一个app:layout_constraintLeft_toRightOf="@+id/btn_01"属性就能够达到了RelativeLayout布局的android:layout_toLeftOf="@id/btn_1"所要的效果。
相对位置的约束属性的格式基本是layout_constraintxxx_toxxxOf=id这种格式,理解起来其实并不难,constraintxxx表明当前控件的约束方向,如上图的效果constraintLeft就是就是btn_02按钮的左边约束。toxxxOf被约束的控件的方向,如上图id是btn_01 就表明与id为btn_01控件的右边方向约束在一块儿。app:layout_constraintLeft_toRightOf="@+id/btn_01"结合起来就是当前控件btn_01按钮的左边与id为btn_01的控件的右边相约束。 关于约束这个词的理解,你能够理解成用带弹性的绳子相链接起来。
下面在展现几个例子:
按钮01 在按钮02的正下方学习

<?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:layout_width="match_parent" android:layout_height="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:text="按钮01"/>

    <Button  android:id="@+id/btn_02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮2" app:layout_constraintLeft_toLeftOf="@+id/btn_01" app:layout_constraintTop_toBottomOf="@+id/btn_01" app:layout_constraintRight_toRightOf="@+id/btn_01"/>


</android.support.constraint.ConstraintLayout>

首先对按钮01 使用app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent" 使得按钮01的左边和顶部与父布局的左边和顶部约束,这样按钮就被固定在左上角。 而后对按钮02 使用app:layout_constraintLeft_toLeftOf="@+id/btn_01"将按钮02的左边与按钮01的左边相约束,而后使用app:layout_constraintTop_toBottomOf="@+id/btn_01" 让按钮02的顶部与按钮01的底部相约束,这样按钮02就在按钮01的正下方。最后使用 app:layout_constraintRight_toRightOf="@+id/btn_01" 让按钮02的右边与按钮01的右边相约束,保持永远对齐。google

二、倾向(bias)

这里写图片描述
倾向分为两个方向 横向和纵向, 也就是说左右和上下两边出现受力不均,形成倾向,好比左边约束的力是右边约束的力之比是9:1atom

<?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:layout_width="match_parent" android:layout_height="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="180dp" android:layout_height="wrap_content" android:layout_marginLeft="80dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:text="按钮01"/>

    <Button  android:id="@+id/btn_02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按钮2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintVertical_bias="0.3" app:layout_constraintHorizontal_bias="0.9"/>


</android.support.constraint.ConstraintLayout>

这里写图片描述
理解:左边的间距占左右边间距之和的90%,上间距占上下间距之和的30%spa

三、圆心定位

这是在1.1版本添加的新属性,貌似没有自动提示
这里写图片描述.net

<?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:layout_width="match_parent" android:layout_height="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_marginLeft="80dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:text="按钮01"/>

    <Button  android:id="@+id/btn_02" android:layout_width="80dp" android:layout_height="wrap_content" android:text="按钮2" app:layout_constraintCircle="@+id/btn_01" app:layout_constraintCircleRadius="90dp" app:layout_constraintCircleAngle="20"/>


</android.support.constraint.ConstraintLayout>

这里写图片描述
圆心定位意思就是基于两个控件的中心,经过radius和angle来控制控件的位置。angle角度不支持负值。默认以被定位控件(btn_01)的Y轴正方向为零度。

四、可见性约束

隐藏前隐藏后
能够看到区别开始是按钮01左边约束父布局的左边,而后按钮02约束按钮01的右边。 可是当按钮01隐藏之后,按钮02直接约束到父布局的左边,事实上按钮根本没有约束父布局的左边。 这里小编的理解,就是以前的隐藏的控件的布局约束依然有效,只不过按钮01的全部边距变成了0.若是你有更好的理解请告诉我,谢谢。

五、控件尺寸约束

一般咱们定义控件的长和宽,android:layout_width=""android:layout_height="" 来设置控件的大小。
ConstraintLayout布局设置方式:

  • 固定值
  • wrap_content
  • 0dp(至关于MATCH_CONSTRAINT)

那match_parent呢?看下面这段话

Important: MATCH_PARENT is not recommended for widgets contained in a ConstraintLayout. Similar behavior can be defined by using MATCH_CONSTRAINT with the corresponding left/right or top/bottom constraints being set to “parent”.

大概意思是不推荐使用match_parent在ConstraintLayout布局中设置大小,相似的功能可使用约束设置左右或者上下指定约束到父布局上。
那怎样实现其余四大布局match_parent沾满父窗体剩下控件的效果呢? 可使用0dp来代替
match_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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_marginLeft="48dp" android:layout_marginTop="112dp" android:text="按钮01" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/>

    <Button  android:id="@+id/btn_02" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="按钮2" app:layout_constraintLeft_toRightOf="@+id/btn_01" app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

这里写图片描述
0dp实现的效果

<?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="match_parent">

    <Button  android:id="@+id/btn_01" android:layout_width="80dp" android:layout_height="wrap_content" android:layout_marginLeft="48dp" android:layout_marginTop="112dp" android:text="按钮01" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent"/>

    <Button  android:id="@+id/btn_02" android:layout_width="0dp" android:layout_height="wrap_content" android:text="按钮2" app:layout_constraintLeft_toRightOf="@+id/btn_01" app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>

这里写图片描述

六、比例(Ratio)

app:layout_constraintDimensionRatio="H,16:9"
app:layout_constraintDimensionRatio="W,16:9"

这里的比例指的是占父布局的高度和宽度的比例

七、链条(Chains)

链条适合于横向或者纵向一排的控件的布局方式。
首先要建立一个链条,就是一排控件首位相互约束,以下图
这里写图片描述
这里写图片描述
相似的效果的代码像这样,建立了一个链条

<?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="match_parent">
    <TextView  android:id="@+id/tab1" android:layout_width="0dp" android:layout_height="40dp" android:background="@android:color/darker_gray" android:gravity="center" android:text="tab1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/tab2" />

    <TextView  android:id="@+id/tab2" android:layout_width="0dp" android:layout_height="40dp" android:background="@android:color/holo_green_light" android:gravity="center" android:text="tab1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/tab1" app:layout_constraintRight_toLeftOf="@+id/tab3" />

    <TextView  android:id="@+id/tab3" android:layout_width="0dp" android:layout_height="40dp" android:background="@android:color/holo_red_light" android:gravity="center" android:text="tab1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/tab2" app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

效果就像这样
这里写图片描述
看似效果跟LinearLayout的比重布局很类似,可是它有和LinearLayout不同的效果,就是给链条添加样式。
这里写图片描述

  • CHAIN_SPREAD 元素被分散开(默认样式)
  • 在CHAIN_SPREAD模式下,若是一些控件被设置为MATCH_CONSTRAINT,那么控件将会把全部剩余的空间均分后“吃掉”
  • CHAIN_SPREAD_INSIDE Chain两边的元素贴着父容器,其余元素在剩余的空间中采用CHAIN_SPREAD模式
  • CHAIN_PACKED Chain中的全部控件合并在一块儿后在剩余的空间中居中

4、总结

看完了关于ConstraintLayout布局属性的介绍,是否是感受很是强大,不只有丰富的相对位置约束,还有比例、倾向的设置,具有RelativeLayoutLinearLayout两个最经常使用布局的各类优势。关键在性能上也有优点,咱们还有什么理由不尝试呢?
参考连接:
https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout
http://www.javashuo.com/article/p-vvqpebme-bt.html

相关文章
相关标签/搜索