原文链接 Android ConstraintLayout运用攻略

ConstraintLayout是新一代的布局,它汲取了众家之长,把布局的概念进行了大统一,灵敏且强壮,基本上能够干掉以前一切的常用布局(LinearLayout, RelativeLayout和FrameLayout)。自从Android Studio 2.3(大约在2017年)后,它就变成了Android Studio的默许模板的布局控件,能够看出谷歌对它的宠爱程度。今天就来学习一下怎么运用这个新布局神器。

Android ConstraintLayout使用攻略

简述

ConstraintLayout与RelativeLayout有些相似,是一个布局管理器(ViewGroup),但要强壮许多,它能够以各种方法摆放子View,以及按份额伸缩。最重要的改动便是它关于『Drag and drop』拖拽式制作GUI页面支持的适当的好。当然了这个取决于个人喜好,很多人依然喜爱用写代码的方法直接去写xml文件,包含我在内。拖拽式虽然直观,可是不便利精准操控,关于一般性的布局来说尚可,但稍复杂了后,以及有了一些可滑动的view时,就不是那么的便利了。关于喜爱拖拽的同学能够查看官方的一个教程,以及郭大婶的一篇文章,这两篇专心于拖拽式,且讲的都比较详细。

添加依赖

由于ConstraintLayout并不是在标准的SDK中,而是被放在了support SDK中,现在统一叫androidx了,所以要单独添加依赖:

     dependencies {
          implementation 'com.android.support.constraint:constraint-layout:2.1.0'
     }

概念与术语

ContraintLayout中把一切有关布局的参数都称之为Constraint(束缚),长和宽,对齐,居中,margin和padding都是constraint。布局中的属性均以”layout_constraint”为前缀。 束缚(Constrain)的意思是指用别的一个View(包含父布局即ContraintLayout)对当时View的某一布局参数施加影响。详细的影响叫做Constraint,别的一个View称作束缚目标(Constraining Object),当时View称作被束缚目标(Constrainted Object)。

Android ConstraintLayout使用攻略

     <Button android:id="@+id/buttonA" ... />
     <Button android:id="@+id/buttonB" ...
          app:layout_constraintLeft_toRightOf="@id/buttonA" />

摆放方法

对子View的摆放方法是一个ViewGroup的最根底的功用,它也体现了不同的布局管理器的效果,如线性布局(LinearLayout)是以水平或许垂直方向平铺方法来摆放子View的。ConstraintLayout是以相似RelativeLayout的方法,需求针对每个子View指定怎么摆放。

Android ConstraintLayout使用攻略

根底摆放方法

最为根底的摆放方法便是针对每个子View,指定它相关于别的一个View或许父布局(也便是ConstraintLayout本身)的相对方位,然后确认该View的详细方位。详细便是[left, top, right, bottom]四个要害的摆放元素相关于别的一个View或许父布局的方位联系。

如,layout_constraintLeft_toLeftOf=”parent”,这便是左面与父布局左面对齐;layout_constraintTop_toBottomOf=”id/header”,这是把这个View放在id为header的下面。以此类推,由于与RelativeLayout的布局参数比较相似,就不细说了,详情可参阅文档。

还有一个十分实用的Constraint叫做baseline,它是专门针对TextView的,baseline也即文本的基线,能够简略理解为文字的底部,当有两个TextiView不相同大,文字巨细也不相同时,却需求对齐文本,这个归于就适当的有用。

Android ConstraintLayout使用攻略

    <TextView android:id="@+id/TextView1"/>
    <TextView
        android:id="@+id/TextView2"
        app:layout_constraintLeft_toRightOf="@+id/TextView1"
        app:layout_constraintBaseline_toBaselineOf="@+id/TextView1"/>

margin

惯例运用与其他布局是相同的,经过layout_margin[Start,End,Left,Right,Bottom,Top]来指定与束缚目标之间的margin,这个不细说了。

需求说一下,ConstraintLayout有一个goneMargin,能够用于当一个束缚目标的Visibility被设置为GONE时,运用。用layout_goneMargin[Start,End,Left,Top,Right,Bottom]来设置。

比方A束缚B,B在A的右边,它俩挨着,但假如A的Visibility设置为GONE时,正常状况下B就会挨到本来A的左面了,跑到了左面界上,这时或许就会变得比较丑了,假如运用margin,比方在A和B中心加一个margin,能够处理问题,可是也会影响当A可见的时分。而用goneMargin就能够完美的处理此种场景。layout_goneMarginStart=”10dip”,那么这个margin只有当束缚目标A的Visibility被置为GONE时,才会收效,这时B虽然跑到了左面界上,可是还有margin,就不会那么丑了。(其实goneMargin运用的场景也比较有限,前面说的case,也能够用A和B的父布局的leftPadding来处理)

Android ConstraintLayout使用攻略

适当骚气的环状摆放方法

除了惯例的行列式摆放以外,这货还十分骚气的能够环状摆放,以束缚目标为圆心,经过视点和半径来束缚方位:

  • layout_constraintCircle 用以指定作为圆心的束缚目标(其他view的id)
  • layout_constraintCircleRadius 被束缚目标与圆心的距离
  • layout_constraintCircleAngle 被束缚目标与横轴的视点(0~360度之间)

Android ConstraintLayout使用攻略
Android ConstraintLayout使用攻略

  <Button android:id="@+id/buttonA" ... />
  <Button android:id="@+id/buttonB" ...
      app:layout_constraintCircle="@+id/buttonA"
      app:layout_constraintCircleRadius="100dp"
      app:layout_constraintCircleAngle="45" />

环状摆放实例

环状摆放虽然骚气,可是实际中好像运用场景不多。

居中与对齐

对齐不是大问题,前面讲的怎么摆放其实便是对齐,选定一个束缚目标后,其他目标都受其束缚,就天然对齐了。

比较常见的问题,以及大部分时分比较麻烦的是居中,平衡与中庸中契合绝大多数审美的,因而布局时,绝大多数状况下都是需求居中的。居中的完成的方法便是两头都束缚于父布局(也即ConstraintLayout),如:

Android ConstraintLayout使用攻略

         <androidx.constraintlayout.widget.ConstraintLayout ...>
             <Button android:id="@+id/button" ...
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent"/>
         </>

居中,其实便是两头的束缚边距各占空余空间的50%,扩展开来,想要完成不彻底居中,两头边距呈必定份额联系,也是能够办到的。比方说黄金份额0.618就比居中好看,这也好办:

Android ConstraintLayout使用攻略

       <androidx.constraintlayout.widget.ConstraintLayout ...>
             <Button android:id="@+id/button" ...
                 app:layout_constraintHorizontal_bias="0.382"
                 app:layout_constraintLeft_toLeftOf="parent"
                 app:layout_constraintRight_toRightOf="parent"/>
      </>

这个份额操控叫bias,能够有Horizontal和Vertical两个方向。

尺度

尺度也便是针对子View的宽与高的束缚,其实大部分时分一些详细的子View的宽与高要么指定巨细,要么是WRAP_CONTENT的,但有些时分或许便是需求愈加的灵敏一些,这时就能够考虑用ConstraintLayout里边的一些特性。宽与高设置为固定巨细或许WRAP_CONTENT时与其他ViewGroup是相同的,不必多说,要想特别一点的便是设置为『0dip』或许MATCH_CONSTRAINT时,就会用其他束缚来决议该View的宽或许高。后边重点讨论有束缚的状况。

默许行为

假如子View的宽或许高设置为了MATCH_CONSTRAINT(或许『0dip』)时,默许的行为是它会占满剩下的可用空间。

Max与Min

还能够加上最大最小的限制:

  • layout_constraintWidth_min and layout_constraintHeight_min : will set the minimum size for this dimension
  • layout_constraintWidth_max and layout_constraintHeight_max : will set the maximum size for this dimension
  • layout_constraintWidth_percent and layout_constraintHeight_percent : will set the size of this dimension as a percentage of the parent

按束缚目标的份额来设置(Percent)

前面的默许行为或许最大最小还算不上啥,其他ViewGroup也有相似参数。最为反常与强壮的是能够按束缚目标的份额来作为此View的宽或许高:

  • The dimension should be set to MATCH_CONSTRAINT (0dp)
  • The default should be set to percent app:layout_constraintWidth_default=”percent” or app:layout_constraintHeight_default=”percent”
  • Then set the layout_constraintWidth_percent or layout_constraintHeight_percent attributes to a value between 0 and 1

本身宽高比(Ratio)

这个是最反常的束缚方法,能够设置一个本身的宽高比,以确认子View的尺度,当然了详细的宽或许高还要以其他束缚方法确认详细尺度,然后再按照设置的宽高比对别的一个进行束缚。比方,完成一个方形的按扭,宽是其本身要求的宽度值(WRAP_CONTENT),设置的宽高比是1:1,所以高度也会跟宽度相同,便是一个方形的按扭了:

        <Button android:layout_width="wrap_content"
                   android:layout_height="0dp"
                   app:layout_constraintDimensionRatio="1:1" />

高级特性

前面讲的是一些根底运用方法,可是这货远不止这些,还有一些十分强壮的功用,下面简略介绍两个。

链(Chains)

在某一个方向上(横着或许竖着)有着彼此束缚的一组子View,会被视为一个链,第一个称作头部(Head),能够运用一些款式以对整个链内的子View都产生影响。

Android ConstraintLayout使用攻略
Android ConstraintLayout使用攻略

这儿的彼此束缚的意思是,比方有上面A,B,C三个子View,那么它们要彼此束缚,也即:

  <ConstraintLayout>
      <A layout_constraintLeft_toLeftOf="parent"
           layout_constraintRight_toRightOf="B" />
      <B layout_constraintLeft_toLeftOf="A"
           layout_constraintRight_toRightOf="C" />
      <C layout_constraintLeft_toLeftOf="B"
           layout_constraintRight_toRightOf="parent" />
  </ConstraintLayout>

就能够,对头部子View A进行款式(Chain style),经过layout_constraintHorizontal_chainStyle来设置:

  • CHAIN_SPREAD — the elements will be spread out (default style)
  • Weighted chain — in CHAIN_SPREAD mode, if some widgets are set to MATCH_CONSTRAINT, they will split the available space
  • CHAIN_SPREAD_INSIDE — similar, but the endpoints of the chain will not be spread out
  • CHAIN_PACKED — the elements of the chain will be packed together. The horizontal or vertical bias attribute of the child will then affect the positioning of the packed elements

Android ConstraintLayout使用攻略

链中的权重(Weighted chains)

默许状况下,子View会均分并占满可用的空间。能够用权重来按份额分配,给子View加上layout_constraintHorizontal_weight后,就会按份额分配,这个与LinearLayout的layoutWeight用法是相同的。

组(Groups)

为了View的烘托性能,各路大神告诉咱们要尽或许的让布局扁平化,可是,假如太扁平了,全都放在一个ViewGroup下面,就会紊乱,特别是像RelativeLayout和ConstraintLayout,子View的摆放方法会产生彼此依赖,会有牵一发起全身的状况出现。为了避免这种状况,就需求对子View进行分组,对页面进行区域划分,把紧密相关的视为一个组。以往,会用一个子ViewGroup把一个组包起来,虽然会加深View的层次,但这样能避免牵一发起全身。

而关于ConstraintLayout来说,有更先进的方法了,它有一个类叫Group,便是专门用来干这件事儿的,但Group目标并不是一个真的子View,这儿的意思是它并不会在View tree中进行烘托,它是专门用于管理归于它的子View的,比便利利对整个组进行Visibility的设置。

神器要怎么运用

前面的介绍就差不多了,ConstraintLayout还是适当的强壮的,如有或许还是尽或许的多用它吧。它的完成上面的确挺复杂的,毕竟功用比较强壮,但它的效率并不差。关于常用的几大布局都能够直接用它来代替。

当线性布局运用(as LinearLayout)

线性布局最大的优势就在于能够用weight的方法来按份额排放,而这个用前面提到的Chain就能够完美的处理。所以,LinearLayout能够彻底抛弃。

当层叠布局运用(as FrameLayout)

FrameLayout的全用场景一般是作为整个运用的根布局,特别是HomeActivity+Fragment这种架构。从纯的功用视点来讲,ConstraintLayout能够彻底完成FrameLayout的一切功用,所以,FrameLayout也能够抛弃。

但从简略便利视点来讲,假如是HomeActivity的根布局,子View都是MATCH_PARENT的Fragement的话,也没有必要换成ConstraintLayout,这种场景FrameLayout彻底够用,而且十分合适它。换成ConstraintLayout反倒有些糟蹋,有些杀鸡用牛刀。

当相对布局运用(as RelativeLayout)

早年面的叙述能够看出,ConstraintLayout简直便是RelativeLayout的加强版。所以,凡是用到RelativeLayout的当地都应该换成ConstaintLayout

参考资料

  • Build a Responsive UI with ConstraintLayout
  • ConstraintLayout
  • 束缚布局ConstraintLayout看这一篇就够了
  • Use ConstraintLayout to design your Android views
  • ConstraintLayout Tutorial for Android: Complex Layouts
  • Constraint Layout Tutorial With Example In Android Studio
  • Android新特性介绍,ConstraintLayout彻底解析

原创不易,打赏点赞在看保藏分享 总要有一个吧