内容简介:码个蛋(codeegg)第 606 次推文作者:TeaOf
码个蛋(codeegg)第 606 次推文
作者:TeaOf
博客:https://www.jianshu.com/p/958887ed4f5f
ConstraintLayout是2016年Google的I/O大会推出的新型布局-约束布局,话说,今年都2019了,ConstraintLayout应该早就被Android工程师熟识了。不过,前几天在群里闲聊的时候,还有人在问:ConstraintLayout好用吗?因此,打算写一篇ConstraintLayout使用总结。
一. 定义
关于这点,我们先看谷歌的官方文档吧:
A ConstraintLayout is a ViewGroup which allows you to position and size widgets in a flexible way.
换成中文就是ConstraintLayout可以灵活的设置其他控件的大小和位置。为什么说灵活呢?因为它可以不用写代码,使用鼠标操控就可以直接实现我们的界面,关于直接使用鼠标操作界面的方式,这里我就不再赘述了,请移步郭神的Android新特性介绍,ConstraintLayout完全解析(https://blog.csdn.net/guolin_blog/article/details/53122387),本文将侧重用代码讲解ConstraintLayout,因为ConstraintLayout本身使用好了就可以减少布局的嵌套。
导入库
我们在正式介绍之前,先在build.gradle文件中添加如下:
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
二. 属性介绍
这里我们先学习一下属性的使用,从基础属性开始吧。如果我直接讲这个属性有什么用可能不是特别清楚,这里我会将这些基础的属性和同类型的RelativeLayout属性进行比较:
对于和left、right相似的start、end基础的属性,这里不再赘述,大家可以自行查阅。当然了,除了一些基础的属性,ConstraintLayout也有自己特有的属性,这里向大家介绍一下常用的属性:
1. bias(偏移量)
长度和高度的偏移量
2. Circular positioning(圆形定位)
以一个控件为圆心设置角度和半径定位
3. Percent dimension(百分比布局)
宽高设置百分比长度
4. Ratio(比例)
控件的宽和高设置一定比例
5. Chain Style(约束链类型)
设置约束链类型,约束链类型包括:spread,spread_inside和packed
三. 具体使用
终于到我们的实战环节了
1. 基础属性的使用
先从设置高度和宽度设置开始吧
1.1 宽度和高度的设置
同普通的控件一样,layout_width和layout_height可以设置如下:
具体的值,例如123dp
wrap_content,让控件计算出适合自己的大小
0dp,等价与match_parent
具体的值和wrap_content这里我就不再多介绍了,大家平时用的不少。唯一有区别的是0dp这个概念,LinearLayout中我们会设置layout_width为0dp,然后搭配layout_weight一起使用,那么我们来看看ConstraintLayout如何使用:
<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"> <ImageView android:id="@+id/iv_beauty" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" android:scaleType="centerCrop" android:src="@drawable/beauty" android:layout_width="200dp" android:layout_height="0dp" /> </android.support.constraint.ConstraintLayout>
我们将高度设置为0dp,看看会发生什么?
与一般布局不一样的是,ImageView的高度相当于整个屏幕的高度,等价于match_parent。0dp完全等价于match_parent其实也不一定完全对,我们再来看一下另外一段代码:
<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"> <!-- iv_beauty宽100高200,放在左上角 --> <ImageView android:id="@+id/iv_beauty" android:layout_width="100dp" android:layout_height="200dp" android:scaleType="centerCrop" android:src="@drawable/beauty" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <!-- iv_girl宽100高0,放在iv_beauty右边,下面与iv_beauty对齐--> <ImageView android:id="@+id/iv_girl" android:layout_width="100dp" android:layout_height="0dp" android:scaleType="centerCrop" android:src="@drawable/girl" app:layout_constraintBottom_toBottomOf="@+id/iv_beauty" app:layout_constraintLeft_toRightOf="@+id/iv_beauty" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
效果:
其实可以看出,0dp也会受各种约束条件限制,在约束条件内占满整个距离。
1.2 父布局右边
以ImageView为例,如果我想将ImageView放在父布局的右边,这时我们需要将layout_constraintRight_toRightOf的值设置为parent,代码如下:
<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"> <ImageView android:id="@+id/iv_beauty" app:layout_constraintRight_toRightOf="parent" android:src="@drawable/beauty" android:layout_width="200dp" android:layout_height="200dp" /> </android.support.constraint.ConstraintLayout>
效果:
这个时候你可能会问,如果我想放在父布局左边,是不是只添加app:layout_constraintLeft_toLeftOf="parent"就对了?聪明!答对了,同理,app:layout_constraintTop_toTopOf="parent"代表放在父布局上边,app:layout_constraintBottom_toBottomOf="parent"代表放在父布局下边,这里不再赘述。
1.3 父布局居中
这个时候,小王同学问了:如果我同时将app:layout_constraintRight_toRightOf="parent"、app:layout_constraintLeft_toLeftOf="parent"、app:layout_constraintTop_toTopOf="parent"和app:layout_constraintBottom_toBottomOf="parent"都加上会怎么样呢?代码如下:
<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"> <ImageView android:id="@+id/iv_beauty" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" android:src="@drawable/beauty" android:layout_width="200dp" android:layout_height="200dp" /> </android.support.constraint.ConstraintLayout>
效果:
我们的ImageView居中了,没错,如果添加app:layout_constraintRight_toRightOf="parent"和app:layout_constraintLeft_toLeftOf="parent"会水平居中,添加app:layout_constraintLeft_toLeftOf="parent"和app:layout_constraintRight_toRightOf="parent"会竖直居中,全部添加就是水平和竖直方向都居中。
2. bias
如果我想ImageView相对于父布局左边间隔1/10个父布局长度,相对于父布局上边间隔2/10个父布局高度,我们该怎实现呢?看代码:
<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"> <ImageView android:id="@+id/iv_beauty" app:layout_constraintHorizontal_bias="0.1" app:layout_constraintVertical_bias="0.2" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" android:src="@drawable/beauty" android:layout_width="200dp" android:layout_height="200dp" /> </android.support.constraint.ConstraintLayout>
效果:
app:layout_constraintHorizontal_bias="0.1"代表水平方向往右偏移10%,app:layout_constraintVertical_bias="0.2"代表竖直方向往下偏移20%。
这里需要注意的是:
想要设置偏移,必须先将控件设置父布局居中。
偏移的长度,如横向的偏移,是父布局宽度减去ImageView宽度的剩下的10%
3. Percent dimension
如果我们想将ImageView的宽度设置为父布局宽度的70%,这个时候我们就可以考虑使用百分比属性了,代码如下:
<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"> <ImageView android:id="@+id/iv_beauty" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.7" android:scaleType="centerCrop" android:src="@drawable/beauty" android:layout_width="0dp" android:layout_height="200dp" /> </android.support.constraint.ConstraintLayout>
效果:
可以看到,我们这里先将layout_constraintWidth_default属性设置为percent,接着将layout_constraintWidth_percent设置为0.7,同理,我们可以对layout_constraintHeight_default和layout_constraintHeight_percent进行高度的设置。这里需要注意的是:
需要先将布局约束之后,才可以进行宽度或者高度的设置,如上述代码,我们先添加了app:layout_constraintTop_toTopOf="parent"和app:layout_constraintLeft_toLeftOf="parent",将ImageView设置在左上角,如果没有先进行控件的约束,会发现我们的设置的百分比这个属性没有起作用。后面的很多属性也是如此,需要先对控件进行约束,才能对我们的控件设置一些属性。
4. Ratio
在日常工作中,我们会经常遇到将控件比如ImageView设置长:宽=2:1,这个时候怎么办呢?这个时候,小王说了,这个简单啊,如果宽设置为200dp,高就设置为100dp,我只能说,没毛病。同样的功能我们也可以通过Ratio实现,看代码:
<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"> <ImageView android:id="@+id/iv_beauty" android:layout_width="200dp" android:layout_height="0dp" android:scaleType="centerCrop" app:layout_constraintDimensionRatio="2:1" android:src="@drawable/girl" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
效果:
如果需要按照比例设置控件,这里需要先将layout_width或者layout_height一方设置为0dp,另一个设置为正常比例,接着给layout_constraintDimensionRatio设置比例,例如app:layout_constraintDimensionRatio="2:1".
5. chain
Chain(约束链)是ConstraintLayout中比较有趣的功能了,我们这次先不看代码,看一下关于约束链的图片,图片来自Medium:
这种动图很好的向我们诠释了约束链的三种类型,分别是spread、spread_inside和packed:
spread:视图均匀分布。
spread_inside:除了约束链的头部和尾部贴在两边的约束上,其余均匀分布。
packed:将视图打包在一起,默认居中。
第一步 建立约束链
什么叫约束链呢,看图:
形成约束链的条件就是如图两个ImageView分别以对方为约束,我们等会儿看代码。
第二步 在第一个控件添加约束链类型
layout_constraintVertical_chainStyle或者layout_constraintHorizontal_chainStyle添加上面介绍的约束链类型。
以spread为例,我们看一下代码:
<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"> <!-- 在第一个控件设置chain_style,第一个和最后一个ImageView也要设置 好约束,上下控件也要互为约束 --> <ImageView android:id="@+id/iv_beauty" android:layout_width="200dp" android:layout_height="100dp" android:scaleType="centerCrop" android:src="@drawable/beauty" app:layout_constraintBottom_toTopOf="@+id/iv_girl" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_chainStyle="spread" /> <ImageView android:id="@+id/iv_girl" android:layout_width="200dp" android:layout_height="100dp" android:scaleType="centerCrop" android:src="@drawable/girl" app:layout_constraintBottom_toTopOf="@+id/iv_biu" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/iv_beauty" /> <ImageView android:id="@+id/iv_biu" android:layout_width="200dp" android:layout_height="100dp" android:scaleType="centerCrop" android:src="@drawable/biu" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/iv_girl" /> </android.support.constraint.ConstraintLayout>
效果:
spread类型的约束链妥妥的完成了,可以根据自己的需求修改约束链类型。
6. GuideLine
GuideLine只能用在ConstraintLayout布局中,用来辅助布局,不会被显示,通常有横向和纵向之分。GuideLine更多的是使用鼠标操控实现布局,不过,我们就简单的讲解一下使用代码的方式,我们的目标是实现两侧分布的效果,看代码(基于上面的spread效果的代码):
<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"> <ImageView android:id="@+id/iv_beauty" android:layout_width="200dp" android:layout_height="100dp" android:layout_marginEnd="8dp" android:scaleType="centerCrop" android:src="@drawable/beauty" app:layout_constraintBottom_toTopOf="@+id/iv_girl" app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_chainStyle="spread" /> <ImageView android:id="@+id/iv_girl" android:layout_width="200dp" android:layout_height="100dp" android:layout_marginStart="8dp" android:scaleType="centerCrop" android:src="@drawable/girl" app:layout_constraintBottom_toTopOf="@+id/iv_biu" app:layout_constraintRight_toRightOf="parent" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/iv_beauty" /> <ImageView android:id="@+id/iv_biu" android:layout_width="200dp" android:layout_height="100dp" android:layout_marginEnd="8dp" android:scaleType="centerCrop" android:src="@drawable/biu" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/guideline" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@+id/iv_girl" /> <!-- Guideline可以设置具体的宽度,也可以设置百分比 --> <android.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.5" /> </android.support.constraint.ConstraintLayout>
效果:
我们这里用的Android studio编辑模式查看的,真实的情况下约束链和Guideline是不会显示的,当Guideline移动的时候以Guideline为约束的控件也会跟着移动。
7. Barrier
Barrier同Guideline一样,不会被显示,你可以理解为Barrier为我们组成了一个虚拟的视图组,不过它没有视图层级的概念。我们看一下Barrier的使用效果:
可以看到,中间的线就是我们的Barrier,会随着左侧控件组的最长侧变化而改变Barrier的位置,从而改变右侧控件的位置。同样推荐使用鼠标操控的方式使用Barrier实现布局,这里只是简单的使用:
<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="100dp" android:background="@drawable/shape_bg"> <ImageView android:id="@+id/iv_biu" android:layout_width="80dp" android:layout_height="80dp" android:scaleType="centerCrop" android:src="@drawable/biu" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@+id/barrier" android:layout_marginStart="10dp" app:layout_constraintTop_toTopOf="parent" /> <!-- constraint_referenced_ids包含我们需要包含的组件,以这些组件的某一侧为基准 --> <!-- barrierDirection面向包含的组件 --> <android.support.constraint.Barrier android:id="@+id/barrier" android:layout_width="wrap_content" android:layout_height="match_parent" app:barrierDirection="right" app:constraint_referenced_ids="tv_name,tv_content" /> <TextView android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="20dp" android:layout_marginStart="20dp" app:layout_constraintLeft_toLeftOf="parent" android:text="Li Lei" android:textSize="20sp" /> <TextView android:id="@+id/tv_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:layout_marginStart="20dp" app:layout_constraintLeft_toLeftOf="parent" android:text="look for bigger world,looking for" android:textSize="16sp" app:layout_constraintBottom_toBottomOf="parent" /> </android.support.constraint.ConstraintLayout>
效果:
什么情况下会使用Barrier呢?当你使用不可控长度的文本或者自定义的控件的时候,可以考虑使用Barrier。
8. Circular positioning
什么是Circular positioning呢?我们可以称之为圆形定位,就是以目标控件为圆心,通过设置角度和半径确定我们当前控件的位置,如官方图:
可以说是简单明了了,那么我们来学习一下简单使用:
<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/iv_biu" android:layout_width="64dp" android:layout_height="64dp" android:scaleType="centerCrop" android:src="@drawable/biu" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginStart="10dp" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/iv_girl" android:layout_width="64dp" android:layout_height="64dp" app:layout_constraintCircle="@+id/iv_biu" app:layout_constraintCircleRadius="120dp" app:layout_constraintCircleAngle="35" android:src="@drawable/girl"/> </android.support.constraint.ConstraintLayout>
效果:
那么Circular positioning可以做什么呢?可以用来设计比较炫酷的动画或者控件:
地址:ConstraintLayout: Circular Positioning(http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/1015/8597.html)
如果想查看关于Circular positioning的进阶使用,可以查看我的另一篇博客:
妙用ConstraintLayout的Circular positioning https://www.jianshu.com/p/7f111f0bdbd0
9. Group
Group的作用感觉比较鸡肋,通过app:constraint_referenced_ids添加对子View的引用,然后统一的显示或者隐藏控件。这里不再赘述。
四. 总结
ConstraintLayout介绍完毕,需要多多使用才能很好的掌握。本人水平有限,难免有误,如有错误,欢迎提出。
Introducing Constraint Layout 1.1 (https://medium.com/androiddevelopers/introducing-constraint-layout-1-1-d07fc02406bc) ConstraintLayout: Circular Positioning(http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2017/1015/8597.html)
官方文档(https://developer.android.com/reference/android/support/constraint/ConstraintLayout)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 推广AndroidX,人人有责。
- 如何在企业各团队间推广开发规范?
- 优普丰十年敏捷推广的心得总结
- 将“softmax+交叉熵”推广到多标签分类问题
- 从这三大方面入手全面解析如何做好小红书推广
- 云资讯 2019可信云大会 | 刘婷:城商行持续交付实践与推广
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
An Introduction to the Analysis of Algorithms
Robert Sedgewick、Philippe Flajolet / Addison-Wesley Professional / 1995-12-10 / CAD 67.99
This book is a thorough overview of the primary techniques and models used in the mathematical analysis of algorithms. The first half of the book draws upon classical mathematical material from discre......一起来看看 《An Introduction to the Analysis of Algorithms》 这本书的介绍吧!