ConstraintLayout - 属性篇

0.294字数 2227阅读 11298

A ConstraintLayout is a ViewGroup which allows you to position and size widgets in a flexible way.
简言:ConstraintLayout是可以灵活设置其内控件位置和大小的ViewGroup

支持API 9 (Gingerbread)及以上,官方后续仍将对其API和功能进行扩展。

添加

1、 Android Studio版本至少2.3
2、 在build.gradle中添加依赖,如下:

dependencies {
    compile 'com.android.support.constraint:constraint-layout:1.0.1'
}

约束类型

当前支持(2017.3)
1、 Relative positioning
2、 Margins
3、 Centering positioning
4、 Visibility behavior
5、 Dimension constraints
6、 Chains
7、 Virtual Helpers objects

注意:在约束条件下不能有循环依赖关系。
详看ConstraintLayout.LayoutParams布局属性。

开发者指南

相对位置 Relative positioning

作用:设置控件与另一个控件的相对位置。

可在水平轴与垂直轴约束控件:

  • 水平轴:Left,、Right,、Start、End
  • 垂直轴:top、bottom、text baseline
Relative Positioning Constraints
序号 属性
1 layout_constraintLeft_toLeftOf
2 layout_constraintLeft_toRightOf
3 layout_constraintRight_toLeftOf
4 layout_constraintRight_toRightOf
5 layout_constraintTop_toTopOf
6 layout_constraintTop_toBottomOf
7 layout_constraintBottom_toTopOf
8 layout_constraintBottom_toBottomOf
9 layout_constraintBaseline_toBaselineOf
10 layout_constraintStart_toEndOf
11 layout_constraintStart_toStartOf
12 layout_constraintEnd_toStartOf
13 layout_constraintEnd_toEndOf

以上属性需要另一个控件的idparent(父容器)作为参考:

<Button 
    android:id="@+id/buttonB" ...
    app:layout_constraintLeft_toLeftOf="parent" />

示例:将按钮B放置到按钮A的右边

Relative Positioning Example
<Button android:id="@+id/buttonA" ... />

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

边距 Margins

作用:设置target控件与source控件的边距。

示例:将按钮B放置到按钮A右边,并设置边距。B:source控件;A:target控件。

Relative Positioning Margins

序号 属性
1 android:layout_marginStart
2 android:layout_marginEnd
3 android:layout_marginLeft
4 android:layout_marginTop
5 android:layout_marginRight
6 android:layout_marginBottom

注意:边距只能设置精确的值(包括0)和尺寸引用。
当位置约束target控件View.GONE时,可用以下margin属性指示不同的边距值:

序号 属性
1 layout_goneMarginStart
2 layout_goneMarginEnd
3 layout_goneMarginLeft
4 layout_goneMarginTop
5 layout_goneMarginRight
6 layout_goneMarginBottom

居中设置 Centering positioning

ConstraintLayout的优势是如何处理不可能的约束。

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

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

以上示例,除非ConstraintLayoutButton的大小完全相同,否则两个约束不会同时满足。

Centering Positioning

这种情况下,约束的作用类似于相反的力牵引控件并均分边距。而控件最终会在父容器中处于居中位置。垂直约束雷同。

偏置 Bias

默认情况下,这种对立的约束会促使控件处于居中位置。此时,可以使用Bias属性来调整位置,以达到两侧边距不同的效果。

序号 属性
1 layout_constraintHorizontal_bias
2 layout_constraintVertical_bias

示例:设置左侧边距为30%代替默认的50%,如图:

Centering Positioning with Bias
<android.support.constraint.ConstraintLayout ...>

    <Button 
        android:id="@+id/button" ...
        app:layout_constraintHorizontal_bias="0.3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent/>
</>

可见性操作 Visibility behavior

ConstraintLayout有特定的方式处理被设置为View.GONE的控件。
通常,设置GONE的控件不会被显示,也不是布局本身的一部分(虽然标记为GONE,但实际尺寸不会改变)。
但是,就布局计算而言,GONE的控件仍是布局的一部分,区别在于:

  • 对于layout pass,尺寸将被看做是0(基本上被处理成了一个点);
  • 如果对其他控件有约束,则仍然会被注重,但是所有边距值都将看似为0。
Visibility Behavior

这种特定的行为允许在可以设置控件暂时为GONE的地方构建布局,并且不影响布局,这对制作简单的布局动画也很有用。

注意:上图使用的边距是由B定义的到A的距离。有些情况下这可能不是想要设置的边距(例:A到父容器一边的边距100dp,BA边距16dp,此时设置AGONE,那么B到父容器边距只有16dp)。出于以上原因,当一个作为参考的控件设置为GONE时,可以使用替代的边距值(详看Margins部分)。

尺寸约束 Dimension constraints

ConstraintLayout 最小尺寸

可以自定义ConstraintLayout的最小尺寸。

  • android:minWidth布局的最小宽度
  • android:minHeight布局的最小高度

ContraintLayout尺寸设置为WRAP_CONTENT时,将使用最小尺寸。

控件尺寸约束

控件尺寸可以通过三种方式设置android:layout_widthandroid:layout_height属性:

  • 使用指定的尺寸(如:123dp、尺寸引用dimen);
  • 使用WRAP_CONTENT,将要求控件自己计算自己的尺寸;
  • 使用0dp,相当于MATCH_CONSTRAINT
Dimension Constraints

前两个类似。最后一个将调整控件,以一致的约束来设置(a:wrap_content;b:0dp)。如果设置了边距,布局计算中将会计算到(c:0dp)。

注意:ContraintLayout中的控件不支持MATCH_PARENT,虽然类似的操作可以使用MATCH_CONSTRAINT与设置相应的left/righttop/bottomparent约束

比例 Ratio

可以定义一个控件相对于另一个控件的尺寸比例。前提是,需要至少设置一个约束的尺寸为0dp(即MATCH_CONSTRAINT),并通过layout_constraintDimentionRatio属性设置比例。

示例:设置Button的高度与宽度相同

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

比例值设置方式:

  • float浮点值:表示宽高间的比例
  • width:height方式表示比例

如果宽高都设置为MATCH_CONSTRAINT (0dp),也可以使用比例Ratio。这种情况下,系统会设置最大的那个尺寸来满足所有约束,并保持指定的宽高比。根据一个有尺寸的控件来约束一个指定约束面的控件。可以预先添加WH来分别约束宽高。例:一个尺寸被两个条件约束(如:宽度0dp并在父容器中居中),那么可以通过在比例Ratio前添加WH,并用,分隔来标识哪一面应该被约束:

<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"/>

高度按照16:9区分,宽度相对父容器按照相同的约束区分。

链 Chains

作用:在单一轴(水平或垂直)上提供群组行为。另一轴可以独立约束。

创建链

Creating a chain
如果一组控件通过双向连接连接在一起,那么这组控件就被认为是一个链。下图显示了一个最小的链。

Chain
链头

Chain heads
链由链的第一个元素(链头)上的属性控制:

  • 水平链链头:最左侧的控件
  • 垂直链链头:最上方的控件
Chain Head
链中的边距

Margins in chains
连接中设置的边距也会计算在内。在链展开的情况下,边距会从分配的空间中扣除。

链样式

Chain Style
当链的第一个元素设置了layout_constraintHorizontal_chainStylelayout_constraintVertical_chainStyle属性,链样式将按照指定的方式改变(默认是CHAIN_SPREAD)。

  • CHAIN_SPREAD:元素将展开(默认);
  • 权重链:CHAIN_SPREAD模式下,如果一些控件设置了MATCH_CONSTRAINT,这些控件将分担可用空间;
  • CHAIN_SPREAD_INSIDE:元素展开,但链的端点不会展开;
  • CHAIN_PACKED:链中的元素将包裹在一起。子控件的水平或垂直方向的偏置bias属性会影响包裹中元素的位置。
Paste_Image.png
权重链

Weighted chains
链的作用是在可用空间内均匀的分布元素。如果一个或多个使用MATCH_CONSTRAINT,它们将抢占可用空间(它们之间均分)。属性layout_constraintHorizontal_weightlayout_constraintVertical_weight可以控制使用MATCH_CONSTRAINT的元素如何分配空间。例:一条链控制了两个使用MATCH_CONSTRAINT的元素,第一个元素权重为2,第二个元素权重为1,那么第一个元素占用的空间是第二个元素的两倍。

辅助类 Virtual Helpers objects

除了设置详细的内置属性,也可以在ConstraintLayout中使用特殊的辅助类来帮助布局。目前,Guideline类创建的水平和垂直的参考,允许ConstraintLayout中的控件作为参考相对定位。参考标准将约束控件的布局。

Guideline

public class Guideline extends View

对于ConstraintLayoutGuideline是一个实用的辅助类。辅助类不会在设备上显示(设置为GONE),并且只用于布局意图。只能在ConstraintLayout中使用。

Guideline可以是水平的或垂直的:

  • 垂直Guideline:宽度为0,高度为父容器constraintlayout高度;
  • 水平Guideline:高度为0,宽度为父容器constraintlayout宽度。

设置Guideline有三种较为合理的方式:

  • layout_constraintGuide_begin:从布局的左侧或顶部指定距离
  • layout_constraintGuide_end:从布局的右侧或底部指定距离
  • layout_constraintGuide_percent:指定一个布局的宽高比

然后,控件可以以Guideline为参考设置约束,允许多个控件以一个Guideline为参考,或者可以使用百分比设置自适应布局。

XML中设置Guideline,详看 ConstraintLayout.LayoutParams 的属性,以及 ConstraintSet 中相应的 [setGuidelineBegin(int, int)](https://developer.android.google.cn/reference/android/support/constraint/ConstraintSet.html#setGuidelineBegin(int, int))、[setGuidelineEnd(int, int)](https://developer.android.google.cn/reference/android/support/constraint/ConstraintSet.html#setGuidelineEnd(int, int))、[setGuidelinePercent(int, float)](https://developer.android.google.cn/reference/android/support/constraint/ConstraintSet.html#setGuidelinePercent(int, float)) 方法。

示例:垂直Guideline约束按钮

<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">

    <android.support.constraint.Guideline
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/guideline"
            app:layout_constraintGuide_begin="100dp"
            android:orientation="vertical"/>

    <Button
            android:text="Button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button"
            app:layout_constraintLeft_toLeftOf="@+id/guideline"
            android:layout_marginTop="16dp"
            app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

出处

Guideline
ConstraintLayout
ConstraintLayoutExamples

推荐阅读更多精彩内容