hust
  • 简介
  • 效率
    • on-my-zsh git alias
    • Markdown写ppt
    • 开发者的Mac工具集合
  • 语言
    • Java
    • Dart
      • 基本语法
      • 基本库
      • 异步编程之Future
      • 异步编程之Stream
    • Kotlin
      • Kotlin中的可空类型
  • Android
    • Native
      • 自定义Material点击效果的View
      • 开源视频播放器JiaoZiVideoPlayer学习
      • ConstraintLayout使用说明
      • 布局文件中的tools命名空间
      • TabLayout使用指南
      • AppBarLayout学习
      • EditText在RecyclerView中的解决方案
      • Jetpack
        • 动画和转换
          • 具有动画效果的图片资源
          • 使用动画隐藏或显示View
          • 使用动画移动View
          • 使用动画缩放图片
          • ViewGroup内容改变时的动画效果—LayoutTransition
          • 在布局切换之间实现Transition动画
          • 在Activity切换之间实现Transition动画
      • Flutter
        • APP的基础——组件
      • 开源库
        • EventBus
          • EventBus简介及初步使用
          • EventBus线程分发
          • EventBus配置、粘性事件、优先级和取消事件分发
          • EventBus源码分析之发布订阅模型
          • EventBus源码分析之线程分发
Powered by GitBook
On this page
  • 官方文档
  • 相对布局
  • Margins
  • 中心布局和bias
  • 圆形布局(1.1加入)
  • 可见性行为
  • 尺寸约束
  • 链
  • 虚拟辅助工具
  • 优化 (1.1新特性)
  • 高级用法——辅助工具
  • Guideline
  • Barrier
  • Group
  • 总结
  1. Android
  2. Native

ConstraintLayout使用说明

Previous开源视频播放器JiaoZiVideoPlayer学习Next布局文件中的tools命名空间

Last updated 6 years ago

刚学Android那会,Android是有五大布局的:FrameLayout、LinearLayout、RelativeLayout、AbsouteLayout、TableLayout。现在为止,Android的布局家族得到了扩充,现在在公司做项目使用的最多的是ConstraintLayout,之前接触的比较少,因此趁着周末时间,好好学习了一下,功能非常nb,不愧是Android Studio默认创建项目的首选布局。

与RelativeLayout类似,但功能更强大,且性能更高。

官方文档

目前ConstraintLayout支持以下几种约束:

  • 相对布局

  • Margins

  • 中心布局

  • 圆形布局

  • 可见性行为

  • 尺寸约束

  • 链

  • 虚拟辅助工具

  • 优化器

相对布局

相对位置是一个最基本的功能,一个控件相对另一个控件是如何布局的。你可以控制在水平和垂直两个方向上控制控件。

  • 水平方向:left、right、start、end边

  • 垂直方向:top、bottom边和文字baseline

layout_constraintXXX_toYYYOf属性,其中XXX和YYY可以为start、left、end、right、top和bottom,意思是让控件的哪一边和另一个控件的哪一边挨着。

用法:

 <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@+id/button1"
        app:layout_constraintTop_toTopOf="parent" />

layout_constraintXXX_toYYYOf属性后面即可跟控件id,也可以跟parent,parent代表着父布局,即ConstrainLayout。

Margins

<?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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        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" />


    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:text="B"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toRightOf="@id/button1"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

当约束的目标可见性是GONE,可以设置一个另外的margin,通过以下属性进行设置:

  • layout_goneMarginStart

  • layout_goneMarginEnd

  • layout_goneMarginLeft

  • layout_goneMarginTop

  • layout_goneMarginRight

  • layout_goneMarginBottom

中心布局和bias

举个例子:

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

如果需要满足这个约束,那么button尺寸得和ConstraintLayout一样宽。但最终的效果如下:

这样就好像拉伸了控件一样,实现了水平居中的效果,同样可用于垂直居中。

Bias

默认地,两边拉伸一样大,但如果想两边拉伸的不一样,可以使用如下两个属性:

  • layout_constraintHorizontal_bias

  • layout_constraintVertical_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/>
         </>

这样两边比就是0.3:0.5,类似LinearLayout的weight效果。

圆形布局(1.1加入)

可以指定某一控件以相对另一控件的某一角度和距离进行布局。

  • layout_constraintCircle : references another widget id

  • layout_constraintCircleRadius : the distance to the other widget center

  • layout_constraintCircleAngle : which angle the widget should be at (in degrees, from 0 to 360)

可见性行为

ConstraintLayout在处理控件可见性为GONE时有特殊的规则。

当控件可见性为GONE时,

  • 布局阶段会认为是一个点

  • 它的约束关系仍在,但是margin会是0。

尺寸约束

ConstraintLayout最小尺寸

可以为ConstraintLayout设置最小尺寸和最大尺寸。当ConstraintLayout的尺寸设置WARP_CONTENT时,这些最小尺寸和最大尺寸会被使用。

控件尺寸约束

控件的尺寸是通过layout_width和layout_height进行约束的,可以使用三种值:

  • 某一指定值

  • WARP_CONTENT

  • 0dp,等价于"MATCH_CONSTRAINT"

Ratio

可以定义控件的尺寸和另一个控件的尺寸比例。前提条件是至少有一个尺寸是0dp,然后指定layout_constraintDimensionRatio,如下:

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

这种情况下,宽高将是1:1。

ratio可以有两种表现形式:

  • 一个浮点数:表示宽/高

  • 一个比例形式,表示宽:高

如果两个尺寸都为0dp,系统根据指定的ratio设置满足的最大尺寸。

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

H字母在前表示,前面是高度:宽度;

链

虚拟辅助工具

  • Guideline

  • Barrier

  • Group

优化 (1.1新特性)

可以在ConstraintLayout中添加app:layout_optimizationLevel进行优化,目前支持的参数有:

  • none : no optimizations are applied

  • standard : Default. Optimize direct and barrier constraints only

  • direct : optimize direct constraints

  • barrier : optimize barrier constraints

  • chain : optimize chain constraints (experimental)

  • dimensions : optimize dimensions measures (experimental), reducing the number of measures of match constraints elements

高级用法——辅助工具

Guideline

可以将Guideline看做是辅助线,不会在布局中显示的。Guideline中有两种,垂直的和水平的。

  • 水平的Guideline,高度为0dp,宽度为ConstraintLayout的宽度

  • 垂直的Guideline,宽度为0dp,高度为ConstraintLayout的高度

有三种方法去定位一个辅助线的位置:

  • layout_constraintGuide_begin:对于水平的,相当于topMargin;对于垂直的,相当于leftMarigin

  • layout_constraintGuide_end:对于水平的,相当于bottomMargin;对于垂直的,相当于rightMarigin

  • layout_constraintGuide_percent:设定相对布局的百分比,如果需要居中,就设置0.5

 <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="parent" />

居左1/4,guideline居中,textview又居左和guideline的中,就是1/4的地方。

Barrier

Barrier以一组控件作为输入,基于这些控件创造出一个虚拟的辅助线。

比如下图,将会创造一个左边的栅栏沿着控件的左边。

<android.support.constraint.Barrier
              android:id="@+id/barrier"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              app:barrierDirection="start"
              app:constraint_referenced_ids="button1,button2" />

当创建了Barrier之后,其他控件可以和Barrier建立约束。

Group

用法如下:

 <android.support.constraint.Group
              android:id="@+id/group"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:visibility="visible"
              app:constraint_referenced_ids="button4,button9" />

总结

ConstraintLayout是一个性能很高的布局,可以应对复杂的布局,重要的还是要多实践实践。

关于相对位置,官方给出的图如下:

和其他布局一样,都是可以指定Margins的,比如在指定了边重合后,可以再加上Margins实现上图的效果。

效果如下图:

是栅栏的意思,Java并发库里有个栅栏,这里意思差不多,都是给个底线,超越不得的。

可以将一组控件组合起来,一起控制可见性。不需要分开设置。这个真的是太有用了,目前我们的项目中经常需要某一中情况下隐藏几个textview,那一种情况下又是开那几个TextView,可以改变用Group。

ConstraintLayou
Barrier
Group
相对位置带Margins
相对位置示意图