注:本博客所以内容均是本人学习记录,参考了很多大佬的博客,有啥侵权的,请联系我
刚开入手Android的时候习惯使用线性布局LinearLayout和RelativeLayout相对布局,这两者布局基本能处理近9成的UI布局,但是存在一定的问题,而且百分比布局用的人很少,后面学习本文记录的google最新推出的布局——约束布局ConstraintLayout
这个布局很强大,一个布局就可以替代线性布局、相对布局、百分比布局、帧布局··· 是一个完全扁平化的布局,不需要嵌套直接了当提升了UI渲染的性能
废话不多说 Let’s go
ConstraintLayout中宽高0代表:MATCH_CONSTRAINT,这个布局通过约束去控制UI的显示,而不是通过设定view的大小
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
一、实现相对布局的上下左右
layout_constraintLeft_toLeftOf:当前View左边在某个View(或者父布局parent)的左边
效果跟下面一样
layout_constraintStart_toStart:当前View开始位置跟某个View(或者父布局parent)的开始位置对齐
layout_constraintRight_toRightOf:当前View右边在某个View(或者父布局parent)的右边
效果跟下面一样
app:layout_constraintEnd_toEndOf="":当前View结束位置跟某个View(或者父布局parent)的结束位置对齐
layout_constraintLeft_toRightOf:当前View左边在某个View(或者父布局parent)的右边
layout_constraintRight_toLeftOf:当前View右边边在某个View(或者父布局parent)的左边
同样的触类旁通:
layout_constraintTop_toTopOf:“”
layout_constraintTop_toBottomOf:“”
layout_constraintBottom_toTopOf:“”
layout_constraintBottom_toBottomOf:“”
这组的用法你也就明白了吧
注:
这么设置就是居中效果
<Button
android:id="@+id/btn_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="返回回调传数据"
android:background="@color/color3"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
二、线性布局的宽高比权重效果:
app:layout_constraintHorizontal_weight=“1” //水平方向权重
app:layout_constraintVertical_weight=“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">
<TextView
android:id="@+id/tab0"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@color/color3"
android:gravity="center"
android:text="tab1"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tab1"
app:layout_constraintHorizontal_weight="1"
/>
<TextView
android:id="@+id/tab1"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="tab2"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tab0"
app:layout_constraintRight_toLeftOf="@+id/tab2"
app:layout_constraintTop_toTopOf="@+id/tab0"
app:layout_constraintHorizontal_weight="1"
/>
<TextView
android:id="@+id/tab2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/color4"
android:gravity="center"
android:text="tab3"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tab1"
app:layout_constraintRight_toLeftOf="@id/tab3"
app:layout_constraintTop_toTopOf="@+id/tab0"
app:layout_constraintHorizontal_weight="2"
/>
<TextView
android:id="@+id/tab3"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="tab4"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tab2"
app:layout_constraintRight_toLeftOf="@+id/tab4"
app:layout_constraintTop_toTopOf="@+id/tab0"
app:layout_constraintHorizontal_weight="1"
/>
<TextView
android:id="@+id/tab4"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/color5"
android:gravity="center"
android:text="tab5"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tab3"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/tab0"
app:layout_constraintHorizontal_weight="1"
/>
</android.support.constraint.ConstraintLayout>
如上图,水平方向的权重例子,你就明白了,tab3占2分 ,其他tab占1分。同样的垂直方向的权重也这么使用!
这个例子也能回顾下前面的左右约束,每个tab左右都有绑定。
四、实现百分比布局、宽高比DimensionRatio
百分比布局,意义非常重要,解决碎片化问题就是没有百分比的出现,现在我们来看一下,如何使用的:
layout_constraintVertical_bias:垂直偏移率。
layout_constraintHorizontal_bias:水平偏移率。
layout_constraintHeight_percent:高度百分比,占父类高度的百分比
layout_constraintWidth_percent:宽度百分比,占父类宽度的百分比
app:layout_constraintDimensionRatio="16:6"这个属性,这里设置宽高比为16:6
比如实现一个首页轮播图,占整个屏幕的百分之三十高度,然后垂直方向的偏移率为0,就有下面的效果图了:
先看下代码:
<ImageView
android:id="@+id/view0"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:textSize="30sp"
android:src="@mipmap/background"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"/>
<ImageView
android:id="@+id/view0"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:textSize="30sp"
android:src="@mipmap/background"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"/>
五、链式效果,chainstyle
layout_constraintHorizontal_chainStyle:横向链
layout_constraintVertical_chainStyle:纵向链
使用这个的时候需要注意布局的宽度是不是0,0会充满屏幕
非0的话就跟官网给的上面的图的排版一样的效果,这个属性很实用,比如多个布局互相约束,但是最后需要他们一起居中,就可以设置layout_constraintHorizontal_chainStyle:“packed”
就像weighted就类似于权重效果,这个属性自己练习下就都熟悉了
spread 宽度为0如图:
<Button
app:layout_constraintHorizontal_chainStyle="spread"
android:id="@+id/btn1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_1"
android:background="@android:color/black"
app:layout_constraintRight_toLeftOf="@id/btn2"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
<Button
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintLeft_toRightOf="@+id/btn1"
android:id="@+id/btn2"
app:layout_constraintRight_toLeftOf="@id/btn3"
app:layout_constraintTop_toBottomOf="@+id/btn_1"
android:background="@android:color/holo_green_dark"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
<Button
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintLeft_toRightOf="@+id/btn2"
android:id="@+id/btn3"
app:layout_constraintTop_toBottomOf="@+id/btn_1"
android:background="@android:color/holo_red_dark"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
六、基准线
app:layout_constraintGuide_percent=“0.8”
一般用的很少,用来对齐,用的时候先设置布局排列方向:
android:orientation=“horizontal(vertical)”
上个效果图应该就懂了
<android.support.constraint.Guideline
android:id="@+id/guide_v"
android:layout_width="1dp"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.7" />
<android.support.constraint.Guideline
android:id="@+id/guide_h"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.8" />
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:text="悬浮按钮"
app:layout_constraintLeft_toRightOf="@id/guide_v"
app:layout_constraintTop_toBottomOf="@id/guide_h"
/>
后面介绍的一些属性都不常用,了解下吧
七、Baseline基线
其实这个用的还行,比如我经常用的登录页面布局
标记的姓名就设置了基准线,绑定跟后面的输入框,下面的电话就没有设置,很明显就可以看出两者的差距,一般用这个属性设置对齐
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名:"
app:layout_constraintBottom_toBottomOf="@+id/et_name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="@id/et_name"
app:layout_constraintBaseline_toBaselineOf="@+id/et_name"
/>
<EditText
android:id="@+id/et_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/tv_1"
app:layout_constraintLeft_toRightOf="@+id/tv_name"
android:hint="请输入你的名字"
android:textSize="12dp"
android:layout_marginTop="100dp"
/>
八、宽高最大最小约束——尺寸限制(Dimensions )
常用:
maxHeight
maxWidth
minWidth
minHeight
不常用:
layout_constraintHeight_max
layout_constraintHeight_min
layout_constraintWidth_max
layout_constraintWidth_min
注:这些属性可以给普通控件设置也可以给ConstraintLayout设置。这些属性的使用跟其他布局里面的使用情况一样,而且就看单词也就明白了
九、圆形布局
通过下面的属性设置就行
app:layout_constraintCircle 引用控件的id
app:layout_constraintCircleAngle 据引用id的角度,从0度到360度
app:layout_constraintCircleRadius 半径(据引用id圆心的距离,可变)
<ImageView
android:id="@+id/ig_1"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="360"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="70"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="170"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="270"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="230"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
十、组(Group)
app:constraint_referenced_ids:(id,id)
这个属性也挺好用,因为可以用这个属性来控制一些布局的显示隐藏啥的
<android.support.constraint.Group
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="ig_2,ig_3"
android:visibility="gone">
</android.support.constraint.Group>
<ImageView
android:id="@+id/ig_1"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
<ImageView
android:id="@+id/ig_2"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="360"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:id="@+id/ig_3"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="70"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="120"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="170"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="270"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher"
app:layout_constraintCircle="@id/ig_1"
app:layout_constraintCircleAngle="230"
app:layout_constraintCircleRadius="50dp"
tools:ignore="MissingConstraints" />
我将部分ig_1,ig_2放到group里面 这样就能控制隐藏显示
十一、Placeholder
placeholder这个词在英文中的意思是占位符,顾名思义,它就是用来占位的。我们直接代码,我的目的是在布局底部的左右两边各放一个Imageview,第一部先创建一个placeholder的文件夹,和平时创建一样,内容如下:
适用场景可以通过这个属性来替换需要显示的布局
还是上个代码例子吧,方便理解:
<android.support.constraint.Placeholder
android:id="@+id/p_1"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:content="@id/p_ig_1"
android:background="@color/color5"
/>
<android.support.constraint.Placeholder
android:id="@+id/p_2"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:content="@id/p_ig_2"
android:background="@color/color5"
/>
<ImageView
android:id="@+id/p_ig_1"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher"/>
<ImageView
android:id="@+id/p_ig_2"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/background"/>
其实也就是先设置一个占位的布局 ,再给他设置conten内容,通过id绑定
作用就这么个作用,具体使用还得看你实际需求,我基本没用过这个布局,然后这个布局也阔以在Java代码中动态的设置content
上面的代码也就是简单的介绍下这个布局的作用,实际用肯定不这么写,好了 下一个
十一、barrier屏障
barrier的属性barrierDirection 指定方向,constraint_referenced_ids引用的控件 id(多个id以逗号隔开)
<android.support.constraint.Barrier
android:id="@+id/barrier_1"
android:layout_width="20dp"
android:layout_height="match_parent"
app:barrierDirection="right"
app:constraint_referenced_ids="p_1"
/>
<android.support.constraint.Placeholder
android:id="@+id/p_1"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@id/barrier_1"
app:content="@id/p_ig_1"
android:background="@color/color5"
/>
十二、ConstraintSet可以和ConstraintLayout布局绑定(也只能是ConstraintLayout)有点类似于帧动画,然后配合TransitionManager实现动画效果,这个我不太了解 后面再查查补充吧