摘要:但是能对已经设置属性的控件进行特殊处理。这同样适用于垂直约束。尺寸在中添加当维度设置为时,默认行为是使结果大小占用所有可用空间。
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言在较新版本的Android Studio中新建项目默认使用 ConstraintLayout进行布局的。
ConstraintLayout是一个允许您以灵活的方式定位和调整小部件的ViewGroup。
注意: ConstraintLayout作为支持库提供,您可以在API级别9(Gingerbread)开始的Android系统上使用。
开发者指南梳理以下内容参考《ConstraintLayout开发者指南》
一、相对定位【Relative positioning】相对定位是在ConstraintLayout中创建布局的基本构建块之一。这些约束允许您将指定的控件(源控件)相对于另一个控件(目标控件)进行定位。您可以在水平和垂直轴上约束控件:
备注:start,end,left,right的区别
1、其中left/right代表一种绝对的对齐,start/end表示基于阅读顺序的对齐。
说到阅读顺序又不得不提目前存在的主要阅读方式: 从左向右(LTR)和从右向左(RTL);
当使用left/right的时候,无论是LTR还是RTL,总是左/右对齐的;而使用start/end,如阅读顺序是从左到右(LTR)的国家,start在左边,在阅读顺序是从右到左(RTL)的国家(比如阿拉伯),start在右边。
2、当minSdkVersion>=17时,建议使用start/end来代替left/right;
当minSdkVersion<17时,旧的平台不支持RTL(从右到左--Right To Left),start/end属性是未知的,会被忽略,所以需要同时使用start/end和left/right。
以下是可用约束属性的列表
用法解析:
1、上面的约束属性一般写在源控件上;
2、约束属性引用的id或者parent代表目标控件;
3、约束属性含义解读:将源控件的指定侧约束到目标控件的其中一侧。
比如:app:layout_constraintLeft_toLeftOf——当前源控件的左侧被约束(constraintLeft)到目标控件的左侧(toLeftOf)
例子1:将按钮B定位在按钮A的右侧,意味着系统将尝试让双方共享相同的位置。
例子2:按钮A和按钮B文本基线对齐,且按钮B在按钮A右侧
二、外边距【Margins】
如果设置了边距,则它们将应用于相应的约束(如果存在约束),系统将边距强制为目标和源边之间的空间。
什么叫边距应用于相应的约束(如果存在约束)?可以简单理解为android:layout_marginLeft和app:layout_constraintLeft_toLeftOf、app:layout_constraintLeft_toRightOf配合使用才会生效!保证设置边距的方向(leftrighttopbottomstartend)和相对定位约束的源控件的方向(leftrighttopbottomstartend)一致!剩下的以此类推!见例子2。
以下是布局边距属性的列表:
用法解析:
1、一般写在源控件上;
2、约束属性含义解读:当前控件(源控件)的指定侧距离与其具有约束关系的控件(目标控件)的其中一侧的空间值;
3、属性值必须是大于或者等于0;
4、当目标控件设置为可见性为gone的时候,源控件的边距仍有效;
例子1:将按钮B定位在按钮A的右侧,并且设置相距8dp
例子2:按钮B和按钮A文本基线对齐,且按钮B的左侧和按钮A的左侧对齐,且边距为8dp
如果去掉app:layout_constraintLeft_toLeftOf属性的话,设置的边距值是无效的,效果如下:
例子3:按钮A隐藏的情况下,按钮B在按钮A右侧,且边距为8dp【此时按钮B的外边距8dp仍是有效的】
三、连接到GONE控件时的边距【Margins when connected to a GONE widget】
当约束目标控件的可见性为View.GONE时
,可以配合使用以下属性设置不同边距值:
和android:layout_MarginLeft等的区别就在于,当目标控件隐藏(GONE)的时候,android:layout_MarginLeft设置的外边距值还生效,而app:layout_goneMarginLeft设置的外边距值则会失效!
例子1:按钮A隐藏的情况下,按钮B在按钮A右侧,且边距为8dp【此时按钮B的外边距8dp是无效的】
四、可见性行为【Visibility behavior】
一般情况下,A控件设置 GONE属性后,A控件就不会出现在布局中了,B控件对A控件的android:layout_MarginXXX属性也就没有作用了。但是 ConstraintLayout 能对已经设置 GONE属性的控件进行特殊处理。当A控件设置 GONE之后,A控件相当于变成了一个点,B控件相对于对A的约束仍然是起作用的,B控件的android:layout_MarginXXX属性还是有作用的。
有时候,B控件是不希望相对于隐藏控件A的属性还起作用。这时候可以用到上面提到的app:layout_goneMarginXXX属性。
例子1:按钮A隐藏后,按钮A的外边距失效,均等于0
初始状态:
设置按钮A的外边距值为5dp:
设置按钮A隐藏状态GONE(可以发现按钮A的外边距5dp失效了):
五、居中定位【Centering positioning】
水平居中(parent表示相对于父节点):
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
垂直居中(parent表示相对于父节点):
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
上图是水平居中的示意图。
ConstraintLayout是如何处理“相反”的约束,比如下面的代码,除非ConstraintLayout恰好具有Button与之完全相同的大小,否则两个约束不能同时满足;在这种情况下发生的事情是,约束的作用就像是相反的力量将控件拉平; 这样控件最终将在父容器中居中。这同样适用于垂直约束。
例子1:按钮A水平居中
例子2:按钮B居中在按钮A中(如果按钮A和按钮B大小一致,那么按钮B就会和按钮A重叠)
五、偏差【Bias】
遇到这种相反的约束时的默认设置是使控件居中(也就是默认偏差50%); 但是您可以使用偏差属性调整定位以使一侧偏向另一侧:
可以使用的属性:
所以,可以得知,偏差属性是需要和“反约束”属性一起使用的。那么什么是“反约束”属性呢?个人简单理解为下面的是反约束属性(仅供参考):
例子1:按钮A水平居偏移30%,按钮B水平居中
六、圆形定位(1.1中增加)【Circular positioning (Added in 1.1)】
您可以以角度和半径距离约束控件中心相对于另一个控件中心。这允许您将控件放在圆上(如下图所示)。
可以使用以下属性:
例子1、按钮B在按钮A的30度角半径为100dp的位置上
七、尺寸约束【Dimensions constraints】 7.1、ConstraintLayout上的最大、最小尺寸约束【Minimum dimensions on ConstraintLayout】
你可以给ConstraintLayout设置以下最大、最小尺寸约束:
当 ConstraintLayout宽高设置为 wrap_content时,以上属性可以起作用。
按照字面的理解是在ConstraintLayout布局控件上设置这些属性,而不是控件上(比如Button、TextView等)设置这些属性。可能这些属性更适合用在ConstraintLayout布局控件上吧。普通控件上也是可以使用的,但是有问题。
例子1:文本A所在的ConstraintLayout区域设置最小宽高,文本B所在的ConstraintLayout区域设置最大宽高
例子2:直接设置文本A的最小宽高,设置文本B的最大宽高【问题:文本B的展现不符合预期】
例子3:按钮A设置最小宽高,按钮B设置最大宽高(注意:Button控件系统默认设置了最小宽高:比如宽88dp,高48dp,去style.xml中AppTheme的父主题里面查看)
7.2、控件尺寸约束【Widgets dimension constraints】
我们可以通过以下3种不同方式设置android:layout_width和android:layout_height属性值指定控件的尺寸。
上图中,(a)是wrap_content,(b)是0dp,如果设置了边距,则在计算中将考虑它们(图8,(c)中的0dp。
重要提示: match_parent不建议用于ConstraintLayout中的控件。可以通过使用match_constraint设置为相应的left/right或top/bottom 约束来定义类似的行为——"parent"。
但是在com.android.support.constraint:constraint-layout:1.1.3中,android:layout_width和android:layout_height属性没有这个match_constraint值。
7.3、wrap_content:强制约束(在1.1中添加)【WRAP_CONTENT : enforcing constraints (Added in 1.1)】如果将维度设置为WRAP_CONTENT,则在1.1之前的版本中,它们将被视为文字维度 - 这意味着约束不会限制生成的维度。虽然通常这足够(并且更快),但在某些情况下,您可能希望使用WRAP_CONTENT,但仍然强制执行约束以限制生成的维度。在这种情况下,您可以添加一个相应的属性:
例子1:文本B在文本A的下方,并且文本B的左侧约束文本A的右侧,文本B的右侧约束parent的右侧(这样可以保证文本全部显示出来)
如果去掉app:layout_constrainedWidth="true",效果如下:文本B的左右约束失效,且文本显示不全!
如果继续去掉app:layout_constraintRight_toRightOf="parent",效果如下:文本B的左右约束还在,但是文本显示不全
7.4、match_constraint(0dp)尺寸(在1.1中添加)【MATCH_CONSTRAINT dimensions (Added in 1.1)】
当维度设置为时match_constraint(0dp),默认行为是使结果大小占用所有可用空间。还有几个额外的修饰符:
注意:使用上面的min、max和percent属性的时候,需要一个方向下只含有一个约束,不能含有两个约束(percent属性可以两个约束)。
比如,app:layout_constraintWidth_min、app:layout_constraintWidth_max,想要生效的话,控件只需要app:layout_constraintLeft_toLeftOf(隐形声明也可以)即可,不能同时含有app:layout_constraintRight_toRightOf="parent"。
例子1:设置文本A的最小宽度值,设置文本B的最大宽度值【可以理解为从左侧开始,设置最小、最大宽度值】
例子2:设置文本A、文本B的宽度占父容器的百分比【可以理解为从左侧开始,文本占百分比】
八、设置宽高比例【Ratio】
当 android:layout_width或者 android:layout_height设置为0dp时,还可以通过 app:layout_constraintDimensionRatio设置宽高比例。该比例表示 width:height的值。
该比率可表示为:
注意:使用app:layout_constraintDimensionRatio属性的时候还是需要至少一个约束,比如可能会忽略的app:layout_constraintLeft_toLeftOf="parent"。
例子1:文本A、文本B宽高比是1:1
如果两个尺寸都设置为MATCH_CONSTRAINT(0dp),您也可以使用比率。
在这种情况下,系统设置满足所有约束的最大尺寸并保持指定的纵横比。要根据另一个特定边的尺寸限制一个特定边,可以预先附加W,“或” H,表示想要约束的宽度或高度。
例如,如果一个尺寸受两个目标约束,则可以指示应该约束哪一边,通过 在比率前添加字母W(用于约束宽度)或H(用于约束高度),用逗号分隔。
例子2:文本A宽度全屏,根据16:9的比率设置高度(要约束的是H)
九、链【Chains】
在横轴或或者竖轴上的控件相互约束时,可以组成一个链式约束。链在单个轴(水平或垂直)上提供类似行的行为。另一个轴可以独立约束。
创建一个链
如果一组控件通过双向连接链接在一起,则它们被视为链。
链头
链由链的第一个元素(链的“头部”)上设置的属性控制:
链头是水平链的最左侧控件,垂直链的最顶部控件。
链的样式
可以通过 app:layout_constraintHorizontal_chainStyle或 app:layout_constraintVertical_chainStyle设置链式控件的样式。这个属性有点像 LinearLayout中的 weight 属性平分布局。
例子1:spread模式
例子2:spread_inside模式
例子3:含有权重spread模式
加权链
链的默认行为是在可用空间中平均分布元素。如果使用了一个或多个元素MATCH_CONSTRAINT(0dp),它们将使用可用的空白空间(在它们之间平均分配)。
属性app:layout_constraintHorizontal_weight和app:layout_constraintVertical_weight 将控制如何将空间利用的元素之间进行分配MATCH_CONSTRAINT(0dp)。例如,在包含两个元素的链上使用MATCH_CONSTRAINT,第一个元素使用权重2,第二个元素使用权重1,第一个元素占用的空间将是第二个元素占用的空间的两倍。
例子3.1:文本B和文本C平分可用空白空间
例子3.2:文本B占2份可用空白空间,文本C占1份可用空白空间
例子4:packed模式
例子5:含有边距的packed模式
链中的边距
如果在链上指定了边距,则会考虑它们。在扩散链的情况下,将从分配的空间中扣除边距。
边距和链条(1.1)
在链中的元素上使用边距时,边距是相加的。
例如,在水平链上,如果一个元素定义了10dp的右边距而下一个元素定义了5dp的左边距,则这两个元素之间产生的边距为15dp。
在计算链用于定位项目的剩余空间时,会同时考虑项目及其边距。剩余空间不包含已设置的边距。
十、辅助布局【Virtual Helper objects】
Guideline对象允许您创建相对于ConstraintLayout容器定位的水平和垂直指南。然后可以通过将小部件约束到这样的指导来定位小部件。在1.1中,Barrier也Group被添加了。
10.1、 Guideline参考《https://developer.android.google.cn/reference/android/support/constraint/Guideline》
Guideline表示约束布局的指导帮助对象的实用工具类。Guideline不显示在设备上(它们被标记为View.GONE),并且仅用于布局目的,它们只在ConstraintLayout中工作。
Guideline可以设置类似于LinearLayout中的orientation属性,设置垂直方向或者水平方向,若设置垂直方向,则水平方向的高度为0,若设置为水平方向,则垂直方向的宽度为0。
Guideline可以是水平的,也是可以是竖直的。通过设置android:orientation属性:
Guideline 具有以下的三种定位方式:
例子1:按钮A和按钮B分别在屏幕一半区域的中间
10.2、 Barrier(Added in 1.1)
参考《https://developer.android.google.cn/reference/android/support/constraint/Barrier》
Barrier,直译为障碍、屏障。在约束布局中,可以使用app:constraint_referenced_ids属性来引用多个带约束的组件,从而将它们看作一个整体。设置app:barrierDirection
属性指定方向。
Barrier是一个虚拟的辅助控件,它可以阻止一个或者多个控件越过自己,就像一个屏障一样。当某个控件要越过自己的时候,Barrier会自动移动,避免自己被覆盖。
例子1:app:barrierDirection="start"效果【注意:建议添加上app:layout_constraintRight_toRightOf="@id/barrier"】
例子2:app:barrierDirection="end"效果【注意:建议添加上app:layout_constraintRight_toRightOf="@id/barrier"】
例子3:表单样式,左侧标签,右侧输入框
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/2342.html
摘要:动画我们这里通过一个示例来说明动画的创建。效果代码评分分无敌破坏王这个页面是我们执行动画结束后的样子。如果需要复杂布局的动画切换,这种方式的优势就非常明显。显然这样会大大增加复杂度和代码量。 介绍 本系列我们已经介绍了ConstraintLayout的基本用法。学习到这里,相信你已经熟悉ConstraintLayout的基本使用了,如果你对它的用法还不了解,建议您先阅读我之前的文章。 ...
摘要:所以这里为时把指向自身,因为自身的肯定符合约束的条件,也是提高布局效率的一个关键点。举一个栗子,在中先让布局之后,根据的,来设置自身的。意味着父控件要依赖子控件的,可能父控件的布局要根据子控件的来做调整。 布局约束 刚才所说的改变一个控件的高度,有时候并不像刚才所说只是改变一下属性就能起作用,这里涉及到一个布局约束规则。直接看BoxConstraints的实现,这个类主要定义了minW...
摘要:双引号单引号区别双引号解释变量,单引号不解释变量双引号里插入单引号,其中单引号里如果有变量的话,变量解释双引号的变量名后面必须要有一个非数字字母下划线的特殊字符,或者用讲变量括起来,否则会将变量名后面的部分当做一个整体,引起语法错误能使单引 双引号单引号区别 双引号解释变量,单引号不解释变量双引号里插入单引号,其中单引号里如果有变量的话,变量解释双引号的变量名后面必须要有一个非数字、字...
阅读 420·2023-04-25 19:43
阅读 3610·2021-11-30 14:52
阅读 3408·2021-11-30 14:52
阅读 3339·2021-11-30 14:49
阅读 3271·2021-11-30 14:49
阅读 3514·2021-11-29 11:00
阅读 3483·2021-11-29 11:00
阅读 3514·2021-11-29 11:00