ConstraintLayout 详解

它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。从 Android Studio 2.3 起,官方的模板默认使用 ConstraintLayout,可见ConstraintLayout的重要性,约束布局非常有利于可视化编程,各种拖拽操作。但是我们实际开发中是不建议使用拖拽,这样写出来的代码维护成本更高。

RelativeLayout 也可以解决多层嵌套问题,但是ConstraintLayout更加灵活,性能更加出色。

适用场合

  1. 追求更高的性能。
    ConstraintLayout 可以有效减少布局的嵌套。绘制过程中的每个阶段都需要对视图树执行一次自顶向下的遍历操作。视图层次结构中嵌套的视图越多,设备绘制视图所需的时间和计算功耗也就越多。


    Android View 绘制过程
  2. 实现动画。
    使用ConstraintLayout可以更加简单实现复杂的动画。

属性分类

ConstraintLayout 目前有 57个属性(还在迭代),相比 LinearLayout 和 RelativeLayout 的学习成本是徒增的,在没有了解他们的属性前,看起来是非常的复杂。由于属性太多,这里把他们分类几类,这样理解起来就简单很多了。

  1. 位置约束 layout_constraintXX_toYYOf(13个)
  2. layout_constraintXX_creator(5个,无意义参数)
  3. layout_goneMarginXX(6个)
  4. 大小约束 layout_constraint[ Width | Height ]_**(10个)
  5. 宽高比例约束 layout_constraintDimensionRatio
  6. layout_constraintCircle**(3个)
  7. 绝对位置(2个)
  8. 参照物 Guideline 组件(3个)
  9. 屏障 Barrier 组件(2个)
  10. Group 组件(和Barrier共享1个)
  11. 占位符 Placeholder (1个)
  12. 其他属性
位置约束 layout_constraintXX_toYYOf(13个)

参数类型:reference|enum,这几个参数可以写@+id/xxx,也可以写parent,所以可以相对其他控件,也可以相对父控件。

这种属性是有规则的,每一个边缘都有2个,还有一个特殊的Baseline_toBaselineOf,是用于定位该控件相对其他控件的位置。如果仅仅使用这类属性布局,1个控件必须设置(左或右)和(上或下)2个属性,否则会提示异常。

  1. Left_toLeftOf
  2. Left_toRightOf
  3. Right_toRightOf
  4. Right_toLeftOf
  5. Top_toTopOf
  6. Top_toBottomOf
  7. Bottom_toBottomOf
  8. Bottom_toTopOf
  9. Start_toStartOf(适配right-to-left布局)
  10. Start_toEndOf(适配right-to-left布局)
  11. End_toEndOf(适配right-to-left布局)
  12. End_toStartOf(适配right-to-left布局)
  13. Baseline_toBaselineOf


    
layout_constraintXX_creator(5个,无意义参数)
  1. layout_constraintBaseline_creator
  2. layout_constraintLeft_creator
  3. layout_constraintRight_creator
  4. layout_constraintTop_creator
  5. layout_constraintBottom_creator

从源码可以看到,这几个参数是没有任何的处理,应该是可视化编辑器使用的,我们不用管这几个参数。

map.append(styleable.ConstraintLayout_Layout_layout_constraintLeft_creator, 39);
map.append(styleable.ConstraintLayout_Layout_layout_constraintTop_creator, 40);
map.append(styleable.ConstraintLayout_Layout_layout_constraintRight_creator, 41);
map.append(styleable.ConstraintLayout_Layout_layout_constraintBottom_creator, 42);
map.append(styleable.ConstraintLayout_Layout_layout_constraintBaseline_creator, 43);

...
int look = ConstraintLayout.LayoutParams.Table.map.get(attr);
int commaIndex;
switch(look) {
 case 0:
 case 39:
 case 40:
 case 41:
 case 42:
 case 43:
 default:
  break;
layout_goneMarginXX(6个)

当参照物为gone时候生效。

  1. layout_goneMarginBottom
  2. layout_goneMarginEnd
  3. layout_goneMarginLeft
  4. layout_goneMarginRight
  5. layout_goneMarginStart
  6. layout_goneMarginTop

下面的例子,两个布局方式的代码是一样的,都设置了app:layout_goneMarginLeft="100dp"app:layout_goneMarginTop="100dp",绿色的布局仅仅把button1隐藏,设置了两个属性就生效了,这几个属性和 ViewGroup layout_marginLeft的效果类似,不同的是参照物设置android:visibility="gone"时候才会生效。

    

        
大小约束 layout_constraint[ Width | Height ]_**(10个)

在约束布局中宽高的维度 match_parent 被 0dp 代替,默认生成的大小占所有的可用空间。那么有以下几个属性可以使用:

  1. layout_constraintWidth_max(dimension|enum:wrap=-2)
  2. layout_constraintWidth_min(dimension|enum:wrap=-2)
  3. layout_constraintHeight_max(dimension|enum:wrap=-2)
  4. layout_constraintHeight_min(dimension|enum:wrap=-2)
  5. layout_constraintWidth_percent(float)
  6. layout_constraintHeight_percent(float)
  7. layout_constrainedHeight(boolean)
  8. layout_constrainedWidth(boolean)
  9. layout_constraintHeight_default(enum:spread, wrap, percent)
  10. layout_constraintWidth_default(enum:spread, wrap, percent)

XX_max 设置最大尺寸,XX_min 设置最小尺寸,XX_percent 置相对于父类的百分比。

layout_constraintHeight_default、layout_constraintWidth_default
这个属性我觉得有点多余,只有percent值有意义,但是也有其他代替方案,不建议使用。

  1. spread:从源代码中看到默认就是spread,实际效果分析,应该等价于android:layout_width="wrap_content"。
  2. wrap:等价 android:layout_width="wrap_content"(已被弃用)
  3. percent:等价 app:layout_constraintWidth_percent="1"

layout_constraintWidth_default="wrap" is deprecated.
Use layout_width="WRAP_CONTENT" and layout_constrainedWidth="true" instead.

layout_constrainedWidth、layout_constrainedHeight
上下两个布局的差别仅仅只是app:layout_constrainedWidth="false",下面的true,当width="wrap_content",如果实际宽度超过了约束的最大宽度,那么约束会失效(高同理),为了防止约束失效,增加了该属性。

layout_constraint[Horizontal | Vertical]_**(6个)
  1. layout_constraintHorizontal_bias(float)
  2. layout_constraintHorizontal_chainStyle(enum:spread, spread_inside, packed)
  3. layout_constraintHorizontal_weight(float)
  4. layout_constraintVertical_bias(float)
  5. layout_constraintVertical_chainStyle(enum:spread, spread_inside, packed)
  6. layout_constraintVertical_weight(float)

当一个控件左右都设置了约束,那么该控件距离左右的目标距离都是一样的,layout_constraintHorizontal_bias默认是0.5,当设置为0.8时候,左边的距离和右边的距离比例就变成了8:2。


    

        

    
宽高比例约束 layout_constraintDimensionRatio(1个)

约束布局支持子控件设置宽高比,前提条件是至少需要将宽高中的一个设置为0dp。为了约束一个特定的边,基于另一个边的尺寸,可以预先附加W,或H以逗号隔开。

假设ImageView1是屏幕的宽度,希望ImageView1是以16:9的形式显示,但是在布局中无法写死Height,那么就可以给ImageView1设置app:layout_constraintDimensionRatio="H,16:9",神操作。设置宽度自适应比例也是同样的原理,app:layout_constraintDimensionRatio="W,16:9"

image.png
    
        
        
        
    
layout_constraintCircle**(3个)
  1. layout_constraintCircle(reference)目标控件 ID
  2. layout_constraintCircleAngle(integer)和目标控件的角度
  3. layout_constraintCircleRadius(dimension)该控件中心 距离目标控件中心的距离。
    
        
绝对位置(2个)

在布局中的绝对位置,很少会用到。

  1. layout_editor_absoluteX(dimension)
  2. layout_editor_absoluteY(dimension)
    
        
参照物 Guideline 组件(3个)

Guideline 与 LinearLayout 类似可以设置水平或垂直方向,android:orientation="horizontal",android:orientation="vertical",水平方向高度为0,垂直方向宽度为0。我们可以创建一些横向的或者纵向的Guideline,在布局界面的时候可以充分利用这些辅助线,对齐我们的View,避免重复写一些marginXXX。

  1. layout_constraintGuide_begin(dimension)
  2. layout_constraintGuide_end(dimension)
  3. layout_constraintGuide_percent(float)
  4. android:orientation(vertical、horizontal)
    
        
        
        
屏障 Barrier 组件(2个)

Barrier,直译为障碍、屏障。在约束布局中,可以使用属性constraint_referenced_ids属性来引用多个带约束的组件,从而将它们看作一个整体,Barrier 的介入可以完成很多其他布局不能完成的功能。

  1. constraint_referenced_ids
  2. barrierDirection(left、right、top、bottom、start、end)

    
    
    
    

Group 组件(共享1个)

Group用于控制多个控件的可见性。

  1. constraint_referenced_ids(可以填写多个ID)


        

        


        
占位符 Placeholder

Placeholder中可设置另一个控件的id,使这个控件移动到占位符的位置。

  1. content(reference)


    
    
其他属性
  1. chainUseRtl(boolean)
  2. constraintSet(reference)
  3. emptyVisibility(gone, invisible)
  4. layout_optimizationLevel(none, standard, direct, barrier, chains, dimensions, groups)

你可能感兴趣的:(ConstraintLayout 详解)