前言:
之前只听说出了constraintlayout这么一个控件,一直没时间研究,今天没事,来学习一下。
本文只作为记录学习,文中若有哪里写的错误的,欢迎大家指正。
借鉴和参考:
http://blog.csdn.net/lmj623565791/article/details/78011599
http://blog.csdn.net/guolin_blog/article/details/53122387
一、介绍:
1、constraint:
英文解释:约束,束缚。constraintLayout总结起来就是通过给控件增加约束条件来固定其位置,用法和RelativeLayout相似,不过比RL更好控制。
2、该控件是一个布局容器,和RelativeLayout、LinearLayout一样,网上搜索大部分是可视化布局拖拽(作者:郭霖),主要是觉得可视化不好控制,用起来不习惯,随后又发现鸿洋大神的文章,遂借来学习学习
先上图,最终实现的效果
注:看到此图,第一想法是LinearLayout或者RelativeLAyout多层嵌套,其实是用Constraint只需要一层即可….
二、下面让我们来学习一下:
1、AS版本>2.2(我用的是2.3)
2、新建一个xml文件
<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"
>
</android.support.constraint.ConstraintLayout>
3、对于内部控件增加约束条件
3-1、先上代码
<ImageView
android:id="@+id/iv1"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@color/colorAccent"
app:layout_constraintLeft_toLeftOf="parent"
/>
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:gravity="center"
android:text="我是name"
app:layout_constraintLeft_toRightOf="@id/iv1"
/>
<TextView
android:id="@+id/tv2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:gravity="start"
android:text="我是content,在此记录描述"
app:layout_constraintLeft_toRightOf="@id/iv1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv1" />
看此代码发现一些没用过,但是又看着眼熟的东西:app:layout_constraintLeft_toRightOf、app:layout_constraintRight_toRightOf等等,发现和RelativeLayout的相对属性很相似。
单拿一个来解释:
app:layout_constraintLeft_toRightOf:用来约束该控件的左边缘和谁的右边缘对齐,后面的值可以是“parent”(父布局),也可以是某一个控件的id(“@id/tv1”)。
相应的还有类似的属性,总结如下:
app:layout_constraintLeft_toLeftOf="" //左侧和谁的左侧对齐
app:layout_constraintLeft_toRightOf="" //左侧和谁的右侧对齐
app:layout_constraintTop_toBottomOf="" //顶部和谁的下边对齐
app:layout_constraintTop_toTopOf="" //顶部和谁的顶部对齐
app:layout_constraintRight_toLeftOf="" //右侧和谁的左侧对齐
app:layout_constraintRight_toRightOf="" //右侧和谁的右侧对齐
app:layout_constraintBottom_toTopOf="" //下边和谁的顶部对齐
app:layout_constraintBottom_toBottomOf="" //下边和谁的下边对齐
此处实现的效果:
大家可能会发现我的所有控件的宽度都设置的是“0dp”,为什么呢?
如果我们把宽度设置为固定值,会出现不可控制的现象,比如设置“100dp”
再比如设置“400dp”
我的理解是当设置固定宽度或高度的时候,或优先根据设置的值来显示控件,当设置为0dp时,会根据自己设置的约束条件来显示控件,这个时候是对控件进行拉伸,以此来达到约束要求,所以总结:在使用constraintLayout时尽量不要设置固定的宽高,使用约束条件,从而达到ui的适配。
3-2、介绍一个新属性,设置宽高比
app:layout_constraintDimensionRatio
<TextView
android:id="@+id/banner"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintDimensionRatio="15:4" //设置宽高比
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
该属性的值还可以这样写:
“W,15:4”//即 宽:高=15:4
“H,15:4” //即高:宽=15:4
默认使用的是第一个
通过设置约束条件来控制控件的宽度或者高度,从而可以确定对应的高度或宽度。
3-3、weight
在LinearLayout中有这一样一个属性weight,可以将包裹的几个控件的高度或宽度进行按照比值进行显示,这么方便的属性,constraintlayout也有同样的属性:app:layout_constraintHorizontal_weight=”1”
根据名字可以猜到 还有app:layout_constraintVertical_weight=””
3-4、链样式
约束布局在使用的时候总会有一个起点,比如上图中的tab1、tab2、tab3,其中tab1就是起点,和后面的2、3构成一条链,可以给起点的控件增加一个属性,控制这条链的显示样式,属性有两种:
//两个属性只能使用一个
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintVertical_chainStyle="spread"
注:该属性只能应用于链状的控件上,像最开始说的iv1、tv1、tv2那样显示的样子,在iv1上设置链样式时是不起作用的。下面我们来看一下各种样式的值:
packed:
设置该值的时候,如果链上各个控件的高度或宽度不能设置为0dp,否则会不显示;
正常设置宽或高之后显示样子:
spread:
使用这个值的时候,会将控件填充满,
如果各个子控件的宽度都为0,会根据设置的weight值来进行显示;
如果没有设置weight值会将链起点填充满整个父控件;
如果每个子控件都设置有宽度,会先将子控件显示完全,如果所有子控件的宽度不能充满父控件的宽度,则会将剩下的宽度进行平分,如下图所示
spread_inside
这个值和上边值的区别在于链的起点和终点始终处于父控件的两侧,子控件宽度无法填充满父控件时也会将剩下的距离进行平分,如下图所示
3-5、下来说说一下bias属性:
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="我是button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
这样设置时该按钮处于parent的中间,如图:
此时拉力A=A1 B=B1,当我们给他设置bias的时候
layout_constraintHorizontal_bias="0.3" //设置控件左侧的拉力
layout_constraintVertical_bias="0.3" //设置控件上边的拉力
此时处于这个位置:
这是A:A1=0.3:0.7 B:B1=0.3:0.7;bias的作用相当于控制该控件与周边控件的距离,和margin有点像。
3-6、最后给大家说一下辅助线的使用:Guideline(android.support.constraint.Guideline)
这是一条辅助线,真实存在,但是不显示
这两条就是辅助线,那个小的textview就位于两条辅助线交叉的坐下放,看代码:
<android.support.constraint.Guideline
android:id="@+id/gui1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8"
/>
<android.support.constraint.Guideline
android:id="@+id/gui2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="adadasd"
android:visibility="visible"
app:layout_constraintRight_toLeftOf="@+id/gui1"
app:layout_constraintTop_toTopOf="@+id/gui2" />
辅助线的位置由下面三个属性来决定其位置
app:layout_constraintGuide_begin="50dp" //辅助线位于距离左边或者顶部50dp
app:layout_constraintGuide_end="50dp" //辅助线位于右边或者底部50dp
app:layout_constraintGuide_percent="0.8" //辅助线位于左边或者顶部0.8的地方,此处设置是按照比值进行定位的
3-6、最后附上全部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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/banner"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/colorPrimaryDark"
app:layout_constraintDimensionRatio="15:4"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv1"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@color/colorAccent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/banner"
/>
<TextView
android:id="@+id/tv1"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:gravity="center"
android:text="我是name"
app:layout_constraintLeft_toRightOf="@+id/iv1"
app:layout_constraintTop_toBottomOf="@+id/banner" />
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:gravity="start"
android:text="我是content,在此记录描述"
app:layout_constraintLeft_toRightOf="@+id/iv1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv1" />
<TextView
android:id="@+id/tvTab1"
android:layout_width="20dp"
android:layout_height="30dp"
android:gravity="center"
app:layout_constraintHorizontal_chainStyle="spread"
android:text="tab1"
android:background="@color/colorPrimary"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tvTab2"
app:layout_constraintTop_toBottomOf="@+id/iv1" />
<TextView
android:id="@+id/tvTab2"
android:layout_width="60dp"
android:layout_height="30dp"
android:gravity="center"
android:background="@color/colorAccent"
android:text="tab2"
app:layout_constraintLeft_toRightOf="@+id/tvTab1"
app:layout_constraintRight_toLeftOf="@+id/tvTab3"
app:layout_constraintTop_toBottomOf="@+id/iv1" />
<TextView
android:id="@+id/tvTab3"
android:layout_width="80dp"
android:layout_height="30dp"
android:gravity="center"
android:text="tab3"
android:background="@color/colorPrimary"
app:layout_constraintLeft_toRightOf="@+id/tvTab2"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/iv1" />
<android.support.constraint.Guideline
android:id="@+id/gui1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8"
/>
<android.support.constraint.Guideline
android:id="@+id/gui2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="adadasd"
android:visibility="visible"
app:layout_constraintRight_toLeftOf="@+id/gui1"
app:layout_constraintTop_toTopOf="@+id/gui2" />
</android.support.constraint.ConstraintLayout>
总结:constraintlayout用法和relativelayout很像,同时也具备了linearlayout的一些功能,非常方便,建议大家多多使用。