约束布局解析
来源:互联网 发布:美团外卖商家mac版本 编辑:程序博客网 时间:2024/06/11 09:02
1、相对定位:
属性都形如 layout_constraint’DIRECTION’_to’TARGET DIRECTION’Of=”TARGET“
1、constraint’DIRECTION’ 里的 ‘DIRECTION’代表是这个子控件自身的哪条边
2、to’TARGET DIRECTION’Of 里的 ‘TARGET DIRECTION’ 代表的是和约束控件的哪条边发生约束
3、TARGET 为目标约束控件对应的 id(父控件的 id 理解为 parent)
2、Margin
1]注意点:
Note that a margin can only be positive or equals to zero, and takes a Dimension
1、只能为正值
2、必须指定维度
1)、只能为正值
当值设置为非正时,会使用默认值 0
margin 值对应的变量都在 LayoutParams 中
源码:
* ConstraintLayout#setChildrenConstraints 方法中设置 margin 相关代码
* 直接代码为:
2)、必须指定“维度”(横向或纵向)
<?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/fixed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fixed" android:layout_marginLeft="50dp" android:layout_marginTop="50dp" /></android.support.constraint.ConstraintLayout>
添加横向维度的“相对“约束时 app:layout_constraintLeft_toLeftOf="parent"
再添加纵向维度的”相对“约束时 app:layout_constraintTop_toTopOf="parent"
2] 要连接的控件 GONE 时 的 margin
layout_goneMargin’DIRECTION’
<?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/fixed" android:layout_width="80dp" android:layout_height="wrap_content" android:text="fixed" android:visibility="visible" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="floating" app:layout_constraintLeft_toRightOf="@+id/fixed" app:layout_goneMarginLeft="120dp" android:layout_marginTop="50dp" app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout>
当 fixed button 设置为 gone 时
tips:在布局编辑器中,将 fixed 的 visibility 设置为 gone 时更容易看出效果
即使 target gone 了,但是其目标对象仍然没变,只不过目标由一个矩形变成一个点了
注意:这个点是 fixed 控件(也就是设置 layout_goneMarginXXX 属性的参照物) “缩小”形成的
这个点的(参照对 MATCH_CONSTRAINT 属性的解释)
* x 坐标是 fixed 控件满足横向约束范围的中间点;(如果 left 未设置参照,那么以 right 参照点为 x 坐标;如果 right 未设置参照,那么以 left 参照点为 x 坐标)
* y 坐标是 fixed 控件满足纵向约束范围的中间点(与 x 坐标同理)
下面这个例子是 left、right、top、bottom 都设置参照点的情况
上图中对应的 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" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/btnFixed" android:layout_width="30dp" android:layout_height="wrap_content" android:text="Fixed" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/btnFixedOther" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> <Button android:id="@+id/btnFixedOther" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintRight_toRightOf="parent" android:text="FixedOther" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@+id/btnFixed" app:layout_goneMarginLeft="100dp" app:layout_constraintBottom_toBottomOf="parent" android:text="floating" /></android.support.constraint.ConstraintLayout>
下面这个例子是 left、right、top 设置了参照点,而 bottom 未设置参照点的情况
上图中对应的 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" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/btnFixed" android:layout_width="30dp" android:layout_height="wrap_content" android:text="Fixed" android:visibility="gone" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toLeftOf="@+id/btnFixedOther" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btnFixedOther" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintRight_toRightOf="parent" android:text="FixedOther" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@+id/btnFixed" app:layout_goneMarginLeft="100dp" app:layout_constraintBottom_toBottomOf="parent" android:text="floating" /></android.support.constraint.ConstraintLayout>
3、居中定位和倾向
1)居中
控件的左边和父控件的左边对齐,控件的右边和父控件的右边对齐
<Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:text="button3" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" /></android.support.constraint.ConstraintLayout>
对比
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:text="button3" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" /></RelativeLayout>
2)倾向(bias)
倾向的值的分配上可以类比 weight
- layout_constraintHorizontal_bias
(0最左边 1最右边) - layout_constraintVertical_bias
(0最上边 1 最底边)
例子:
<Button android:layout_width="wrap_content" android:layout_height="200dp" android:text="floating" app:layout_constraintHorizontal_bias="0.6" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintVertical_bias="0.7" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" />
注意:图中红色箭头只是辅助理解作用
横向:(目标值:0.6)
200 / (200 + 134) = 0.5988
248 / (248 + 183) = 0.5754
竖向:
1、
目标值:0.7
291 / (291 + 126) = 0.6978
402 / (402 + 238) = 0.6281
2、
目标值:0.8
332 / (332 + 83) = 0.8
444 / (444 + 197) = 0.69
4、尺寸约束
1)最小尺寸
对应属性为 wrap_content 时起作用
* android:minWidth
* android:minHeight
2)控件尺寸约束
- 确切的值
- wrap_content
- 0dp( match_constraint )
注意没有 match_parent
可以这么理解,也可以自己试一下,当某个方向上设置为 match_parent 时,对应方向上的所有约束都不再生效了,但是“约束布局”本身最重要的是约束
MATCH_CONSTRAINT
在对应的约束方向上充满“约束的最大范围”
约束的最大范围:
比如:(此处只说横向)
<Button android:id="@+id/button2" android:layout_width="wrap_content" app:layout_constraintLeft_toRightOf="@+id/button1" app:layout_constraintRight_toLeftOf="@+id/button4" android:layout_height="wrap_content" android:text="button2" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="80dp" />
预计:
约束的最大范围时两个红色箭头之间的距离(也就是两个虚线之间的范围)
实际:
再比如:
<Button android:id="@+id/button3" android:layout_width="wrap_content" app:layout_constraintLeft_toRightOf="@+id/button1" app:layout_constraintRight_toRightOf="parent" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@id/button2" android:text="button3" />
预计:
约束的最大范围是两个红色箭头之间的距离(也就是两个虚线之间的范围)
实际:
5、比例
tips:至少一个约束维度设置为 0dp(MATCH_CONSTRAINT),并将 layout_constraintDimentionRatio 设定为给定的比例
比例可以为一个浮点数,或者 width:height
的形式
如果两个约束维度都不是 0dp ,那么比例设置无效
如果两个约束维度都是 0dp 时,系统会使用满足所有约束条件和比率的最大尺寸
6、链条
几个组件之间通过双向连接链接到一起时,可以认为这几个组件形成了链条
样式:
1、spread 分散开的
* 分散开的:(layout_constraintXXX_chainStyle 默认是此模式)
分散时包含组件外部
* 内部分散开的
分散时只包含组件内部
* (铺满)加权分散开的
有组件链条对应维度的大小设置为 0dp( MATCH_CONSTRAINT ) , 此时整个链条会铺满对应维度;
比如横向上有两个组件组成链条时:
2、packed 挤在一起的
tips:此模式下如果将组件的链条对应维度大小设置为 0dp( MATCH_CONSTRAINT ),那么设置0dp 的会不显示(注意与 spread 模式区分)
- 挤在一起的
默认居中 - 有偏向性的挤在一起的
只能由 head 组件指定倾向( bias )
7、Guideline
辅助 ConstraintLayout 的工具类
* vertical
纵向;宽度为零,高度为 ConstraintLayout 的高度
* horizontal
横向;高度为零,宽度为 ConstraintLayout 的高度
定位Guideline有三种方式:
* 指定距离左侧或顶部的固定距离(layout_constraintGuide_begin)
* 指定距离右侧或底部的固定距离(layout_constraintGuide_end)
* 指定在父控件中的宽度或高度的百分比(layout_constraintGuide_percent)
设置固定距离
<android.support.constraint.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_begin="100dp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Button" app:layout_constraintLeft_toLeftOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent"/>
设置百分比
<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.6" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Button" app:layout_constraintLeft_toLeftOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent"/>
同时设置固定距离和百分比
<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.6" app:layout_constraintGuide_begin="100dp" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Button" app:layout_constraintLeft_toLeftOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent"/>
虽然显示 100,但是实际距离还是按照百分比算的,以下为原因
android.support.constraint.solver.widgets.Guideline
public void setGuidePercent(float value) { if(value > -1.0F) { this.mRelativePercent = value; this.mRelativeBegin = -1; this.mRelativeEnd = -1; } } public void setGuideBegin(int value) { if(value > -1) { this.mRelativePercent = -1.0F; this.mRelativeBegin = value; this.mRelativeEnd = -1; } } public void setGuideEnd(int value) { if(value > -1) { this.mRelativePercent = -1.0F; this.mRelativeBegin = -1; this.mRelativeEnd = value; } }
============================
动态
tips:一定注意最后要调用
ConstraintSet#applyTo
方法
1、ConstraintsSet 创建方式
- Manually
c = new ConstraintSet(); c.connect(....);
- from a R.layout.* object
c.clone(context, R.layout.layout1);
- from a ConstraintLayout
c.clone(clayout);
2、各属性对应代码:
1)相对定位
void connect (int startID, int startSide, int endID, int endSide, int margin) Create a constraint between two widgets.
例如:xml
app:layout_constraintLeft_toLeftOf="parent"
对应代码:
constraintSet1.connect(R.id.tvTurn, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT);
tips:如果设置某维度非居中的对齐方式,尽量把维度对应的另一个方向也设置上,设置为 UNSET
原因:之前控件为居中的,现在改为右对齐时,如果只设置一个方向,那么不会生效
如右对齐时:
constraintSetDemo.connect(R.id.demoView, ConstraintSet.LEFT, ConstraintSet.UNSET, ConstraintSet.LEFT); constraintSetDemo.connect(R.id.demoView, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT);
2、margin
基本规则与 xml 中一致
设置 margin 时遇到的问题:
表象:
涉及到左右 margin 的都无效
原因:
暂时不知道
Stack Overflow 上也有个类似问题,不过没人说是怎么回事,猜测是 bug
https://stackoverflow.com/questions/44129278/adding-constraints-to-a-view-in-a-constraintlayout-ignore-left-and-right-margins解决方式:
把 left 改成 start,right 改成 end,目前基本都是从左往右的;
比如
constraintSet3.setMargin(R.id.iconCompass, ConstraintSet.START, (int) ViewHelper.dpToPx(100, getApplicationContext()));
- 约束布局解析
- 约束布局
- 约束布局
- Android新特性---ConstraintLayout(约束布局)完全解析
- 代码创建布局约束
- ios自动布局 约束
- masonry 约束布局
- Android 约束布局constrainLayout
- 约束布局基础
- Android ConstraintLayout 约束布局
- Android 约束布局constrainLayout
- Android ConstraintLayout约束布局
- ConstraintLayout(约束布局)
- ConstraintLayout约束布局
- ConstraintLayout(约束布局)
- Android ConstraintLayout 约束布局
- android 约束布局案例
- Android 约束布局
- JavaScript的变量作用域和闭包操作
- 前后端分离开发的介绍、原因、相关案例
- MVC模型构建管理系统
- LockSupport
- Dalivik垃圾回收收机制Cocurrent GC简介
- 约束布局解析
- vue-quill-editor自定义图片上传
- 机器学习----特征工程
- openwrt系统+ 交叉编译mosquitto
- 图片框架 三重更新 联网解析json设置默认图片以及图片圆角弧度 储存到sd卡
- Android移动开发-检测点击按键事件的实现
- git 添加权限管理gitolite
- opencv(c++)图像处理(imgproc模块)
- 7-7 悄悄关注(25 分)