美高梅4688官方网站现做如下如下记录,都添加了约束

升级Android Studio 2.3之后,IDE默认生成的Activity布局都是以ConstraintLayout做为根布局,体验了一把这个Google去年就开始力推的ConstraintLayout后,觉得非常不错,本文用于记录ConstraintLayout各个方面的使用知识。

前言

  • 首先来看下官方文档的介绍:

    A ConstraintLayout is a ViewGroup which allows you to position and size
    widgets in a flexible way。

    可以把 ConstraintLayout 理解为 RelativeLayout 的升级版

  • 优势

    ConstraintLayout 可以大大的减少布局嵌套,在测量/布局阶段的性能比 RelativeLayout 大约高 40%

    参考文章:
    解析 ConstraintLayout 的性能优势

  • 准备工作

    • AndroidStudio 的版本请升级到 2.2 及以上

    • 在 app 下的 build.gradle 添加以下依赖

      compile 'com.android.support.constraint:constraint-layout:1.0.2'

ConstraintLayout在AS2.2时候就有了,2.3时代作为了AS EmptyActivity模板的默认xml,现做如下如下记录

平台支持

  • ConstraintLayout最低兼容Android 2.3;
  • 目前Android Studio 2.3默认使用ConstraintLayout作为布局文件的根布局;
  • 想要使用ConstraintLayout,需在项目的build.gradle添加com.android.support.constraint:constraint-layout:XXX版本号依赖;

实践

  • 在 xml 文件中添加一个居中显示的 Button

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout ...>
    
        <Button
            android:id="@+id/btnA"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
    
    </android.support.constraint.ConstraintLayout>
    

美高梅4688官方网站 1

01.png

可以看到,给 Button 的 上下左右 都添加了约束,并且是相对 parent 的约束。如果一个控件没有添加任何约束,运行之后自动位于屏幕的左上角

  • 在 ButtonA 的上方添加一个 ButtonB ,左侧对齐,间隔 10 dp

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android" ...>
    
        <Button
            android:id="@+id/btnA"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A" .../>
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:text="B"
            app:layout_constraintBottom_toTopOf="@id/btnA"
            app:layout_constraintLeft_toLeftOf="@id/btnA"/>
    
    </android.support.constraint.ConstraintLayout>
    

美高梅4688官方网站 2

02.png

app:layout_constraintLeft_toLeftOf 约束 ButtonB 的左侧和 ButtonA
的左侧对齐,和 RelativeLayout 的 android:layout_alignLeft 效果一样

app:layout_constraintBottom_toTopOf 约束 ButtonB 的底部在 ButtonA 的顶部,和 RelativeLayout 的 android:layout_above 效果一样

相信你对 ConstraintLayout 的属性有一定的理解了,下面简单的将 ConstraintLayout 和 RelativeLayout 的常用属性做一个对比

RelativeLayout ConstraintLayout
android:layout_toLeftOf app:layout_constraintRight_toLeftOf
android:layout_toRightOf app:layout_constraintLeft_toRightOf
android:layout_above app:layout_constraintBottom_toTopOf
android:layout_below app:layout_constraintTop_toBottomOf
android:layout_alignLeft app:layout_constraintLeft_toLeftOf
android:layout_alignRight app:layout_constraintRight_toRightOf
android:layout_alignTop app:layout_constraintTop_toTopOf
android:layout_alignBottom app:layout_constraintBottom_toBottomOf
android:layout_alignBaseline app:layout_constraintBaseline_toBaselineOf

其实这些属性所显示的效果是一样的,那么我们为什么还要费力气学习这个布局了,下面介绍下这个布局自己独有的属性:

  • Bias

    Bias 即偏压的意思,可以设置约束偏相某一侧的压力。属性如下:

    app:layout_constraintVertical_bias
    app:layout_constraintHorizontal_bias

    取值范围为 0 ~ 1,尝试使用这个两个属性,在屏幕的右下方添加一个 FloatingActionButton

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android" ...>
    
        <android.support.design.widget.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.9"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.9"/>
    
    </android.support.constraint.ConstraintLayout>
    

美高梅4688官方网站 3

03.png

  • Guideline

    Guideline 为辅助线,不会在界面上显示,用于辅助布局。其属性

    android:orientation 取值为 vertical 或 horizontal

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"...>
    
        <android.support.constraint.Guideline
            android:id="@+id/guideline_v"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5"/>
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="LEFT"
            app:layout_constraintRight_toLeftOf="@id/guideline_v"
            app:layout_constraintTop_toTopOf="parent"/>
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="RIGHT"
            app:layout_constraintLeft_toRightOf="@id/guideline_v"/>
    
    </android.support.constraint.ConstraintLayout>
    

美高梅4688官方网站 4

0.4.png

app:layout_constraintGuide_percent 的意思为占父容器 宽度高度 的比例。除此之外,Guideline 还有以下两个属性:

app:layout_constraintGuide_begin 距离父容器 左侧顶部 的距离
app:layout_constraintGuide_end 距离父容器 右侧底部 的距离

  • Chain

    Chain链可以通过两两交叉,平分屏幕剩余空间。实现 LinearLayout 的 android:layout_weight 等分效果

     <?xml version="1.0" encoding="utf-8"?>
      <android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"...>
    
          <TextView
              android:id="@+id/tv_a"
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:background="#FFDF769A"
              android:gravity="center"
              android:text="A"
              android:textSize="20sp"
              app:layout_constraintHorizontal_chainStyle="spread"
              app:layout_constraintLeft_toLeftOf="parent"
              app:layout_constraintRight_toLeftOf="@id/tv_b"/>
    
          <TextView
              android:id="@+id/tv_b"
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:background="#FFD14172"
              android:gravity="center"
              android:text="B"
              android:textSize="20sp"
              app:layout_constraintLeft_toRightOf="@id/tv_a"
              app:layout_constraintRight_toLeftOf="@id/tv_c"/>
    
          <TextView
              android:id="@+id/tv_c"
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:background="@color/colorAccent"
              android:gravity="center"
              android:text="C"
              android:textSize="20sp"
              app:layout_constraintLeft_toRightOf="@id/tv_b"
              app:layout_constraintRight_toRightOf="parent"/>
    
      </android.support.constraint.ConstraintLayout>
    

美高梅4688官方网站 5

05.png

app:layout_constraintHorizontal_chainStyle 一共有三种模式

spread

spread_inside

packed

套用官方的一张图一看便知

美高梅4688官方网站 6

chains-styles.png

给每个 View 添加 app:layout_constraintHorizontal_weight 属性,就可以实现 LinearLayout 的按比例展示,等价于上图的第三条展示效果。


基础使用

ConstraintLayout翻译成中文也称为约束布局,在整个使用体验过程中真的是贯穿约束二字,这一节先来介绍一些基础使用,后面你就会慢慢感受到约束布局的魅力。创建完工程后打开布局文件,底部切换Design的Tab上,可以看到整个操作界面

美高梅4688官方网站 7

左上角的面板是放置了系统内置各种各样的控件,想要布局直接拖到到布局文件中即可(所见即所得),右边的面板是选中布局文件中的控件时期各种各样的空间属性,ConstraintLayout最大的好处在于让我们通过拖控件的形式进行布局,并且不用担心适配问题。所以,先来拖个控件试试看,将一个Button拖动到屏幕正中央,然后运行显示看看效果。

美高梅4688官方网站 8

美高梅4688官方网站 9模拟器运行后的效果

而实际运行后却发现,这个Button还是位于屏幕左上角,说好的居中效果呢?这里就要开始引入ConstraintLayout的约束概念,我们切换回去看xml的布局代码,发现了两个问题。第一,布局预览时能够看到显示居中的Button,是因为控件属性设置中引用了两个tools命名空间下的属性。

美高梅4688官方网站 10

我们都知道,这两个属性只在布局编辑器的预览中有效,实际运行效果是不生效的。第二,Button标签下有红色波浪线警告,我们把鼠标移到对应位置会发现警告内容,告诉我们Button没有任何约束设置,当前效果只支持预览,实际运行后会返回到左上角去,同时提示我们应该给控件添加约束。

美高梅4688官方网站 11

如何增加约束?回到Design页面,对着控件上下左右四个原点拖动添加对应的约束即可

美高梅4688官方网站 12

成功添加约束后,即可得到正常的运行效果了。

美高梅4688官方网站 13

实际操作不一定要在Tab,也可以直接在Text页面拖动控件添加约束

美高梅4688官方网站 14

成功实现添加约束后,可以看到Button多了下面几个属性设置

美高梅4688官方网站 15

app:layout_constraintBottom_toBottomOf=”parent” 意思是Button底部的布局约束是位于parent的底部,parent是指包裹着它的ConstraintLayout,也可以设置指定某个控件的id,其他类似的属性就不再赘述,以上四个约束联合起来便实现了Button的居中,ConstraintLayout总共有下面这些同类的属性

美高梅4688官方网站 16

你会发现ConstraintLayout非常灵活的把RelativeLayout的活给干了,关于left、right、top、bottom、start、end、baseline的基准可以参照下图

美高梅4688官方网站 17

如果我想加多一个Button2并且将其放置到原先居中Button的右方并且与其底部对齐,只需如下操作即可

美高梅4688官方网站 18

并且你也可以发现,Button2依赖与Button后会随着Button的移动而跟着发生相对移动,目的是了保证我设置的依赖,时刻保持Button2就在Button的右边,并且底部对齐。你也可以看到布局文件中也为Button2添加了如下两个属性

美高梅4688官方网站 19

如果你已经理解上面提到的属性含义,这里应该不会有疑惑。

介绍完上下左右的依赖设置后,下面介绍一些Margin属性,除了Android常见的各种android:layout_marginXXX外,ConstraintLayout自行添加了如下属性

美高梅4688官方网站 20

这些设置生效于当依赖的约束对象被设置visibility为gone时,非常简单,读者自行设置实践对比即可,这里就不展示效果了。

聊完Margin后,再来介绍一下Bias,ConstraintLayout新增了如下两个属性用于控制控件在水平和垂直方向在屏幕上的偏移比例

美高梅4688官方网站 21

当为目标控件设置好横纵向的约束时(app:layout_constraintLeft_toLeftOf=”parent”、app:layout_constraintRight_toRightOf=”parent”或者app:layout_constraintTop_toTopOf=”parent”、app:layout_constraintBottom_toBottomOf=”parent”),这个两个属性才会生效。实际操作过程中,你会发现对着设置好横纵向约束的Button进行拖动,布局中的layout_constraintHorizontal_bias和layout_constraintVertical_bias会一直发生相应的变化,如果你需要Button居中,那么直接将这两个属性的参数值设置为0.5即可。

美高梅4688官方网站 22

关于ConstraintLayout的基本使用,这一节就介绍到这里。

结语

ConstraintLayout 融合了 RelativeLayout 和 LinearLayout 的特性,有效的减少了布局的嵌套。以上就是笔者在日常工作中,对 ConstraintLayout的一些用法。第一次写博,不足之处,欢迎大家指证。

转自:http://blog.coderclock.com/2017/04/09/android/android-constraintlayout/

进阶使用

看完基本使用,再来学习一些进阶技巧,这里先补充一个关于ConstraintLayout的知识点,与其他Layout不同之处在于,它的layout_width和layout_height不支持设置match_parent,其属性取值只有以下三种情况:

  • wrap_content;
  • 指定具体dp值;
  • 0dp(match_constraint),代表填充约束之意,注意不要以为和match_parent是一样的;

想想如果没有ConstraintLayout,我们要让一个控件的宽高按某个比例进行布局应该怎么做?有了ConstraintLayout后,我们可以使用layout_constraintDimentionRatio属性设置宽高比例,前提是目标控件的layout_width和layout_美高梅4688官方网站,height至少有一个设置为0dp,如下让一个ImageView宽高按照2:1的比例显示

美高梅4688官方网站 23

layout_constraintDimentionRatio默认参数比例是指宽:高,变成高:宽可以设app:layout_constraintDimensionRatio=”H,2:1”。

ConstraintLayout的链条(Chains)特性非常强大,在没有ConstraintLayout之前,线性布局我们主要都依靠LinearLayout来完成,有了ConstraintLayout之后,它把LinearLayout的活也干了,例如要把按钮水平排成一行,可以这样操作

美高梅4688官方网站 24

这样ButtonA、B、C就在水平方向形成了一条Chain,并且底部对齐。回去看xml文件,会见到ButtonA新增app:layout_constraintHorizontal_chainStyle的属性设置,这个属性在一条Chain中只会出现在第一个控件中,这个控件是整条Chain的Head。

美高梅4688官方网站 25

除了水平方向的layout_constraintHorizontal_chainStyle外还有垂直方向的layout_constraintVertical_chainStyle,两者均有spread,spread_inside,packed这三种取值,如果将控件的layout_width和layout_height设置成为0dp,还可以配合layout_constraintHorizontal_weight、layout_constraintVertical_weight两个属性实现和LinearLayout中设置layout_weight相同的效果,具体的操作这里就不再展示了,下面一张图告诉你Chain的强大之处。

美高梅4688官方网站 26

关于Chain的就介绍到此,进阶的最后一部分再介绍一下Guideline功能,如果我们需要对着屏幕的中轴线进行布局,就可以使用到Guideline进行操作,例如下面两个Button分别分布在中轴线的左右两侧

美高梅4688官方网站 27

从操作上我们可以看到Guideline也分为垂直和水平两种,并且支持设置在屏幕中所处的位置,可以使用layout_constraintGuide_begin和layout_constraintGuide_end设置具体dp值,也可以使用layout_constraintGuide_percent来设置比例。实际上它也只是一个辅助我们布局的View而已,其源码内部实现也非常简单,并且默认设置了visibility为gone,关于ConstraintLayout的进阶使用便介绍到这里。


使用优势

关于ConstraintLayout的使用优势,我个人体验总结如下:

  • 高效布局,Android这么多年以来真正意义上的实现了所见即所得的拖曳方式布局,极大的提高开发效率;
  • 轻松灵活的实现复杂的布局;
  • 解决多重布局嵌套问题,通过前面介绍你会发现ConstraintLayout真的是非常灵活,可以很大程度的避免Layout之间的嵌套;
  • 满足屏幕适配的需求,想想没有ConstraintLayout之前的拖曳式布局,你就知道有多恶心;

1- 基本使用:

  • ConstraintLayout最大的好处在于让我们通过拖控件的形式进行布局,并且不用担心适配问题。

美高梅4688官方网站 28

constraint_1.png

我们先关注 下部分那个TextView
xml 里反应出的代码如下

美高梅4688官方网站 29

constraint_2.png

<TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="20sp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="8dp"
        app:layout_constraintVertical_bias="0.802" />

app:layout_constraintBottom_toBottomOf=”parent”
意思是TextView底部的布局约束是位于parent的底部,
parent是指包裹着它的ConstraintLayout,
也可以设置指定某个控件的id,其他类似的属性就不再赘述,以上四个约束联合起来便实现了Button的居中,ConstraintLayout总共有下面这些同类的属性:

美高梅4688官方网站 30

constraint_3.png

你会发现ConstraintLayout非常灵活的把RelativeLayout的活给干了,关于left、right、top、bottom、start、end、baseline的基准可以参照下图:

美高梅4688官方网站 31

constraint_4.png

现:欲增加一个Btn 与原有Btn底部对齐,且 在原有Btn 右侧,只需按如下写:

美高梅4688官方网站 32

Constraint_5.gif

xml里表现如下:

<Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/textView"
        android:layout_marginLeft="8dp"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginRight="8dp"
        app:layout_constraintRight_toRightOf="parent" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2"
        android:layout_marginLeft="32dp"
        app:layout_constraintLeft_toRightOf="@id/button"
        app:layout_constraintBottom_toBottomOf="@id/button"
        />

至此,button2 依赖了button后,随着button移动,button2也移动,

最佳实践

ConstraintLayout最开始出来就有很多开发者盼着完全依赖于拖曳方式实现布局,而在实际操作过程中,完全通过拖曳其实效率反倒是会打折扣,在此建议是拖曳方式和xml编码相结合才是最佳实践的方式。

1.1 Widgets dimension constraints

The dimension of the widgets can be specified by setting the android:layout_width and android:layout_height attributes in 3 different ways:

  • Using a specific dimension (either a literal value such as 123dp or a Dimension reference)
  • Using WRAP_CONTENT, which will ask the widget to compute its own size
  • Using 0dp, which is the equivalent of "MATCH_CONSTRAINT"
    组件 的尺寸有如下三种设置方法:
  • 固定大小
  • WRAP_CONTENT,让系统让组件自己决定大小
  • 0dp 相当于 MATCH_CONSTRAINT
1.2 Dimensions constraints

Minimum dimensions on ConstraintLayout
You can define minimum sizes for the ConstraintLayout itself:

android:minWidth set the minimum width for the layout
android:minHeight set the minimum height for the layout
Those minimum dimensions will be used by ConstraintLayout when its dimensions are set to WRAP_CONTENT.

1.2 约束尺寸

你可以给ConstraintLayout自己设置最小尺寸,组件的最小尺寸,将在组件被设置为WRAP_CONTENT 时 生效

2- 一些Margin属性:

除了Android常见的各种android:layout_marginXXX外,ConstraintLayout自行添加了如下属性:

美高梅4688官方网站 33

constraint_6.png

这些设置生效于当依赖的约束对象被设置visibility为gone时,非常简单,读者自行设置实践对比即可,这里就不展示效果了。

0418 UPDATE

https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout.html

2.1 Visibility behavior 关于View的Gone:

ConstraintLayout has a specific handling of widgets being marked as View.GONE.
对于Gone的组件ConstraintLayout 有一套特殊的处理方式
GONE widgets, as usual, are not going to be displayed and are not part of the layout itself (i.e. their actual dimensions will not be changed if marked as GONE).
通常情况下Gone的组件,是不被展示而且 不作为layout本身的一部分的(也就是说:这些Gone的组件,一旦给了Gone属性,其本身的尺寸将不会改变)
But in terms of the layout computations, GONE widgets are still part of it, with an important distinction:
但是,在layout计算方面,Gone的组件,仍然是layout计算的一部分,这里有一个重要区别:

  • For the layout pass, their dimension will be considered as if zero (basically, they will be resolved to a point)
    • 为了layout 能通过,Gone的组件的 尺寸将被认为是 0 ,(基本上,他们会被当做一个点来处理,笔者记: 这都在layout的preview里可以直观看到)
  • If they have constraints to other widgets they will still be respected, but any margins will be as if equals to zero

    • 如果,某个Gone的组件 和其他组件之间有约束,那么这个Gone的组件仍然是被系统重视的,但是,他的任何margins 会被认为 是 0

美高梅4688官方网站 34

constraint_gone_margin.png

This specific behavior allows to build layouts where you can temporarily mark widgets as being GONE, without breaking the layout (Fig. 6), which can be particularly useful when doing simple layout animations.

ConstraintLayout的这种特殊的行为,造成了 它允许你在布局的时候,能临时的把某个组件Gone,而不需要打破整个layout布局,(见上图),这一点,在实现一下简单的layout动画时,尤为常用
**Note: **The margin used will be the margin that B had defined when connecting to A (see Fig. 6 for an example). In some cases, this might not be the margin you want (e.g. A had a 100dp margin to the side of its container, B only a 16dp to A, marking A as gone, B will have a margin of 16dp to the container). For this reason, you can specify an alternate margin value to be used when the connection is to a widget being marked as gone (see the section above about the gone margin attributes).
注意:<font color=#00ffff size=72>color=#00ffff</font>
真正被使用的margin 实际上是: B 在与 A 建立联系时,给B设置的margin.
在某些情况下,这可能不是你想咬的margin值(举个栗子: A 有一个100dp 的margin到他的parent容器,B 左margin A 16dp,现在,让A Gone,这时候,B 将margin parent容器 16dp,这特么就尴尬了),为了解决这个问题,你可以特别的声明一个margin 值 即layout_goneMarngLeft = 100dp(笔者记:个人认为,没测试)专门又来解决 当自己联系的组件被Gone时,margin 不准的情况,具体的见上文蓝色文字链接.

3- Basic 属性:

Bias属性,ConstraintLayout新增了如下两个属性用于控制控件在水平和垂直方向在屏幕上的偏移比例,
在本文开头的TextView 中可以看到这样一条属性: app:layout_constraintVertical_bias="0.802"

只有:当为目标控件设置好横纵向的约束时:

  • app:layout_constraintLeft_toLeftOf=”parent”
  • app:layout_constraintRight_toRightOf=”parent”
  • app:layout_constraintTop_toTopOf=”parent”
  • app:layout_constraintBottom_toBottomOf=”parent”

这个两个属性才会生效
注意,这里需要上下左右都有约束,否则basic 属性没用的.
实际操作过程中,你会发现对着设置好横纵向约束的Button进行拖动,布局中的layout_constraintHorizontal_bias和layout_constraintVertical_bias会一直发生相应的变化,如果你需要Button居中,那么直接将这两个属性的参数值设置为0.5即可。

4- 进阶使用:

0526 UPDATE


http://www.jianshu.com/p/32a0a6e0a98a


视图尺寸

ConstraintLayout也支持自动填充宽高, 把宽高设置为0dp会根据位置自动填充. 如, Large按钮, 左侧与Small按钮的左侧对齐, 右侧与constraintLayout(父控件)的右侧对齐, 宽度设置为0dp, 则会填充全部空位.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:id="@+id/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/small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Small"
        app:layout_constraintStart_toStartOf="@id/constraintLayout"
        app:layout_constraintTop_toTopOf="@id/constraintLayout"/>

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Large"
        app:layout_constraintBottom_toBottomOf="@id/constraintLayout"
        app:layout_constraintEnd_toEndOf="@id/constraintLayout"
        app:layout_constraintStart_toEndOf="@id/small"
        app:layout_constraintTop_toTopOf="@id/constraintLayout"/>

</android.support.constraint.ConstraintLayout>

美高梅4688官方网站 35

width_0.png

View的尺寸

我们已经讨论了许多关于View如何放置的问题。现在我们来讨论下关于View尺寸的问题。关于为View指定尺寸,ConstraintLayout的方式可能与你以往使用的不大一样。ConstraintLayout提供了三种方式用于指定子View的尺寸:

Exact: 为子View指定一个确切的尺寸。
将layout_width或layou_height设为一个非零尺寸值(xx dp)即可

Wrap Content: 使子View的尺寸正好“包裹”子View的内容
将layout_width或layout_heigth设为wrap_content即可

Any Size: 让子View填满父容器的剩余空间
将layout_width或layout_heigth设为0dp即可

什么鬼!match_parent跑哪去了?实际上ConstrainLayout不支持match_parent,至于为什么,后文会进行解释。简单的说就是Any Size就已经实现了match_parent的功能。

我们来看一个例子:

<ConstraintLayout
  xmlns:android="..."
  xmlns:app="..."
  android:id="@+id/constraintLayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <Button
    android:id="@+id/button_cancel"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="@+id/constraintLayout"
    app:layout_constraintTop_toTopOf="@+id/constraintLayout"/>

  <Button
    android:id="@+id/button_next"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toEndOf="@+id/button_cancel"
    app:layout_constraintEnd_toEndOf="@+id/constraintLayout"
    app:layout_constraintTop_toTopOf="@+id/constraintLayout"
    app:layout_constraintBottom_toBottomOf="@+id/constraintLayout" />

</ConstraintLayout>

我们可以看到,button_next在指定尺寸时,使用了Any Size方式:它的layout_width被设为了0dp,这意味着它会在水平方向填满父布局的剩余可用空间。显示效果如下:

美高梅4688官方网站 36

width_00.png

ConstraintLayout也支持自动填充宽高, 把宽高设置为0dp会根据位置自动填充. 如, Large按钮, 左侧与Small按钮的左侧对齐, 右侧与constraintLayout(父控件)的右侧对齐, 宽度设置为0dp, 则会填充全部空位.

4.1 宽高比:

补充一个关于ConstraintLayout的知识点,与其他Layout不同之处在于,它的layout_width和layout_height不支持设置match_parent,其属性取值只有以下三种情况:

  • wrap_content;
  • 指定具体dp值;
  • 0dp(match_constraint),代表填充约束之意,注意不要以为和match_parent是一样的;

想想如果没有ConstraintLayout,我们要让一个控件的宽高按某个比例进行布局应该怎么做?有了ConstraintLayout后,我们可以使用layout_constraintDimentionRatio属性设置宽高比例,前提是目标控件的layout_width和layout_height至少有一个设置为0dp,如下让一个ImageView宽高按照2:1的比例显示:

美高梅4688官方网站 37

constraint_7.png

layout_constraintDimentionRatio默认参数比例是指宽:高,变成高:宽可以设app:layout_constraintDimensionRatio=”H,2:1”。其效果与:
app:layout_constraintDimensionRatio=”1:2”是一样的

You can also use ratio if both dimensions are set to MATCH_CONSTRAINT (0dp). In this case the system sets the largest dimensions the satisfies all constraints and maintains the aspect ratio specified. To constrain one specific side based on the dimensions of another.
You can pre append W," or H, to constrain the width or height respectively. For example, If one dimension is constrained by two targets (e.g. width is 0dp and centered on parent) you can indicate which side should be constrained, by adding the letter W (for constraining the width) or H (for constraining the height) in front of the ratio, separated by a comma:
我们也可以把长宽,都设为0dp,再给组件设置app:layout_constraintDimensionRatio,在这种情况下,系统将给组件设置一个能满足所有约束且维护给定长宽比 的最大尺寸

我们也可通过附加:W 或 H,来在宽高方向上分别限制,例如:
假设,一个尺寸被两个目标约束:(例如:宽度0dp,居parent 容器中央),你可以通过W 或 H 来指明,到底在那个方向来约束宽高比,如下:

 <Button android:layout_width="0dp"
                   android:layout_height="0dp"
                   app:layout_constraintDimensionRatio="H,16:9"
                   app:layout_constraintBottom_toBottomOf="parent"
                   app:layout_constraintTop_toTopOf="parent"/>

这个Btn 高度将遵循16:9,同时btn宽度将充满Constrants

美高梅4688官方网站 38

Constraint_ratio_H.png

美高梅4688官方网站 39

Constraint_ratio_H_2.png

4.1 链 式的使用 :

ConstraintLayout的链条(Chains)特性非常强大,在没有ConstraintLayout之前,线性布局我们主要都依靠LinearLayout来完成,有了ConstraintLayout之后,它把LinearLayout的活也干了,例如要把按钮水平排成一行,可以这样操作:

美高梅4688官方网站 40

Constraint_8.gif

这样ButtonA、B、C就在水平方向形成了一条Chain,并且底部对齐。回去看xml文件,会见到ButtonA新增app:layout_constraintHorizontal_chainStyle的属性设置,这个属性在一条Chain中只会出现在第一个控件中,这个控件是整条Chain的Head。

美高梅4688官方网站 41

Constraint_chain_instruction.png

NOTE: AS 2.3 中并未出现:app:layout_constraintHorizontal_chainStyle,最后自己手动加上了这个属性,其有三个可取的值:

  • packed
  • spread
  • spread_inside
    效果分别如下:

美高梅4688官方网站 42

Constraint_chain_packed_8.png

美高梅4688官方网站 43

Constraint_chain_sparead_8.png

美高梅4688官方网站 44

Constraint_chain_spread_inside.png

默认效果是这样的:

美高梅4688官方网站 45

Constraint_chain_default_8.png

可以看出:默认效果 和 sparead 是一样的
笔者认为,这里的这种布局方式 可以 参考 html 里的flex 布局
附上 三个 Button 的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">


    <Button
        android:id="@+id/buttona"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button a"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/buttonb"
        app:layout_constraintVertical_bias="0.203"

        />

    <Button
        android:id="@+id/buttonb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button b"
        app:layout_constraintBottom_toBottomOf="@+id/buttona"
        app:layout_constraintRight_toLeftOf="@+id/buttonc"
        app:layout_constraintLeft_toRightOf="@+id/buttona"

        />

    <Button
        android:id="@+id/buttonc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button c"
        app:layout_constraintBottom_toBottomOf="@+id/buttonb"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/buttonb"

        />
</android.support.constraint.ConstraintLayout>

除了水平方向的layout_constraintHorizontal_chainStyle外还有垂直方向的layout_constraintVertical_chainStyle,两者均有spread,spread_inside,packed这三种取值,如果将控件的layout_width和layout_height设置成为0dp,还可以配合layout_constraintHorizontal_weight、layout_constraintVertical_weight两个属性实现和LinearLayout中设置layout_weight相同的效果,具体的操作这里就不再展示了,下面一张图告诉你Chain的强大之处。

美高梅4688官方网站 46

Constraint_chain_instruction2.png

5- Guideline

如果我们需要对着屏幕的中轴线进行布局,就可以使用到Guideline进行操作,例如下面两个Button分别分布在中轴线的左右两侧

美高梅4688官方网站 47

Constraint_guildline.gif

Guideline也分为垂直和水平两种,并且支持设置在屏幕中所处的位置,可以使用如下三种模式:

  • layout_constraintGuide_begin
  • layout_constraintGuide_end设置具体dp值,
    也可以使用
  • layout_constraintGuide_percent来设置比例。
    实际上它也只是一个辅助我们布局的View而已,其源码内部实现也非常简单,并且默认设置了visibility为gone,关于ConstraintLayout的进阶使用便介绍到这里。

总结:

使用优势:

  • 高效布局,Android这么多年以来真正意义上的实现了所见即所得的拖曳方式布局,极大的提高开发效率;
  • 轻松灵活的实现复杂的布局;
  • 解决多重布局嵌套问题,通过前面介绍你会发现ConstraintLayout真的是非常灵活,可以很大程度的避免Layout之间的嵌套;
  • 满足屏幕适配的需求,想想没有ConstraintLayout之前的拖曳式布局,你就知道有多恶心;

最佳实践:

ConstraintLayout最开始出来就有很多开发者盼着完全依赖于拖曳方式实现布局,而在实际操作过程中,完全通过拖曳其实效率反倒是会打折扣,在此建议是拖曳方式和xml编码相结合才是最佳实践的方式。

本文由美高梅4688官方网站发布于最新话题,转载请注明出处:美高梅4688官方网站现做如下如下记录,都添加了约束

您可能还会对下面的文章感兴趣: