美文网首页Android
ConstraintLayout基本使用

ConstraintLayout基本使用

作者: 全球顶尖伪极客 | 来源:发表于2021-08-24 08:51 被阅读0次

    ConstraintLayout官方文档 | 郭霖托拉拽 | 代码实现

    image.png

    一、相对位置、相对定位Relative positioning

    水平和垂直方向至少得有一个约束

    • Horizontal Axis: left, right, start and end sides
    • Vertical Axis: top, bottom sides and text baseline

    image.png

    1.1、相对定位常用属性,

    • layout_constraintLeft_toLeftOf
    • layout_constraintLeft_toRightOf
    • layout_constraintRight_toLeftOf
    • layout_constraintRight_toRightOf
    • layout_constraintTop_toTopOf
    • layout_constraintTop_toBottomOf
    • layout_constraintBottom_toTopOf
    • layout_constraintBottom_toBottomOf
    • layout_constraintBaseline_toBaselineOf 基线,参考1-3
    • layout_constraintStart_toEndOf
    • layout_constraintStart_toStartOf
    • layout_constraintEnd_toStartOf
    • layout_constraintEnd_toEndOf

    1.2图例解析

    image.png image.png image.png

    1-1 1-2 1-3

    1-1
    <Button android:id="@+id/buttonA" ... />
             <Button android:id="@+id/buttonB" ...
                     app:layout_constraintLeft_toRightOf="@+id/buttonA" />
                         
                         
      1-2                   
        <TextView
            android:id="@+id/TextView1"
            ...
            android:text="TextView1" />
    
        <TextView
            android:id="@+id/TextView2"
            ...
            app:layout_constraintLeft_toRightOf="@+id/TextView1" />
    
        <TextView
            android:id="@+id/TextView3"
            ...
            app:layout_constraintTop_toBottomOf="@+id/TextView1" />
                
      1-3       
      <TextView
            android:id="@+id/TextView1"
            .../>
    
        <TextView
            android:id="@+id/TextView2"
            ...
            app:layout_constraintLeft_toRightOf="@+id/TextView1" 
            app:layout_constraintBaseline_toBaselineOf="@+id/TextView1"/>
    

    二、边距Margins

    注意事项:控件在ConstraintLayout里面要实现margin,必须先约束该控件在ConstraintLayout里的位置。在使用margin的时候要注意两点:控件必须在布局里约束一个相对位置,margin只能大于等于0

    image.png

    2.1常用属性

    • android:layout_marginStart

    • android:layout_marginEnd

    • android:layout_marginLeft

    • android:layout_marginTop

    • android:layout_marginRight

    • android:layout_marginBottom

    <android.support.constraint.ConstraintLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:id="@+id/TextView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp" 
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
            //需要下面的约束
            //app:layout_constraintLeft_toLeftOf="parent"
            //app:layout_constraintTop_toTopOf="parent"/>
    </android.support.constraint.ConstraintLayout>
    

    2.2 goneMargin,连接到 GONE 小部件时的边距

    说明:goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值

    常用属性:

    • layout_goneMarginStart

    • layout_goneMarginEnd

    • layout_goneMarginLeft

    • layout_goneMarginTop

    • layout_goneMarginRight

    • layout_goneMarginBottom

    假设TextView2的左边约束在TextView1的右边,并给TextView2设一个app:layout_goneMarginLeft="10dp",代码如下:

    <android.support.constraint.ConstraintLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:id="@+id/TextView1"
            .../>
    
        <TextView
            android:id="@+id/TextView2"
            ...
            app:layout_constraintLeft_toRightOf="@+id/TextView1"
            app:layout_goneMarginLeft="10dp"
            />
    
    </android.support.constraint.ConstraintLayout>
    

    效果如下2-1,TextView2在TextView1的右边,且没有边距。这个时候把TextView1的可见性设为gone,TextView1消失后,TextView2有一个距离左边10dp的边距。效果如下:2-2

    image.png 2-1 image.png

    2-2

    三、居中和偏移Centering positioning and bias

    居中:

    image.png
    <android.support.constraint.ConstraintLayout ...>
                 <Button android:id="@+id/button" ...
                     app:layout_constraintLeft_toLeftOf="parent"
                     app:layout_constraintRight_toRightOf="parent
                     app:layout_constraintBottom_toBottomOf="parent
                    app:layout_constraintTop_toTopOf="parent"/>
             </>
             居中
    

    偏移:

    说明:赋一个范围为 0-1 的值,假如赋值为0,则TextView1在布局的最左侧,假如赋值为1,则TextView1在布局的最右侧,假如假如赋值为0.5,则水平居中,水平竖直方向value="0.3"相当于weight百分比占比

    常见属性:

    • layout_constraintHorizontal_bias
    • layout_constraintVertical_bias

    image.png
    <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/>
             </>
    

    写上具体的偏移值:

    上面TextView1在水平居中后使用layout_marginLeft="100dp"向右偏移了100dp

    image.png
    <TextView
            android:id="@+id/TextView1"
            ...
            android:layout_marginLeft="100dp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />
    

    四、角度定位Circular positioning (Added in 1.1)

    说明:您可以相对于另一个小部件中心以某个角度和距离约束小部件中心。这允许您将一个小部件放置在一个圆圈上(见图 6)。

    角度从垂直方向顺时针,类似钟表。

    相关属性:

    • 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)
    image.png
    
    <Button android:id="@+id/buttonA" ... />
      <Button android:id="@+id/buttonB" ...
          app:layout_constraintCircle="@+id/buttonA"
          app:layout_constraintCircleRadius="100dp"
          app:layout_constraintCircleAngle="45" 
          app:layout_constraintLeft_toLeftOf="parent"
          app:layout_constraintRight_toRightOf="parent"
          app:layout_constraintTop_toTopOf="parent"
          app:layout_constraintBottom_toBottomOf="parent"
              />
             
         
    

    Visibility behavior

    尺寸约束Dimensions constraints

    • android:minWidth set the minimum width for the layout
    • android:minHeight set the minimum height for the layout
    • android:maxWidth set the maximum width for the layout
    • android:maxHeight set the maximum height for the layout

    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)
    • 使用wrap_content,让控件自己计算大小,Using WRAP_CONTENT, which will ask the widget to compute its own size
    • 使用 0dp (MATCH_CONSTRAINT),Using 0dp, which is the equivalent of "MATCH_CONSTRAINT"
    <TextView
                android:id="@+id/TextView4"
                android:layout_width="0dp"
                android:layout_height="110dp"
                android:background="@color/black"
                android:layout_marginLeft="30dp"
                app:layout_constraintDimensionRatio="w,1:1"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
    image.png

    宽高比

    当宽或高至少有一个尺寸被设置为0dp时(并且当一个0为0时另外一个至少是一个具体的数值,不能为****wrap_content,不然看着没有啥效果),可以通过属性layout_constraintDimensionRatio设置宽高比

    • app:layout_constraintDimensionRatio="H,2:3"指的是 高:宽=2:3
    • app:layout_constraintDimensionRatio="W,2:3"指的是 宽:高=2:3
    <TextView
            android:id="@+id/TextView4"
            android:layout_width="0dp"
            android:layout_height="110dp"
            android:background="@color/black"
            app:layout_constraintDimensionRatio="w,1:1"  正方形
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    

    链:Chains

    • 链在单个轴(水平或垂直)上提供类似组的行为。另一个轴可以独立约束。
    • 如果一组小部件通过双向连接链接在一起,则它们被认为是一个链(显示了一个最小链,具有两个小部件。
    image

    链头:Chain heads

    链由设置在链的第一个元素(链的“头”)上的属性控制:头部是水平链最左边的小部件,垂直链是最顶部的小部件。

    image

    链中的边距Margins in chains

     <TextView
            android:id="@+id/TextView11"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#685454"
            android:text="ff0000"
            app:layout_constraintHorizontal_chainStyle="spread_inside"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toLeftOf="@+id/TextView12"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@+id/TextView12"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#00ff00"
            android:text="00ff00"
            app:layout_constraintLeft_toRightOf="@+id/TextView11"
            app:layout_constraintRight_toLeftOf="@+id/TextView13"
            app:layout_constraintRight_toRightOf="parent" />
    
        <TextView
            android:id="@+id/TextView13"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#0000ff"
            android:text="0000ff"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toRightOf="@+id/TextView12"
            app:layout_constraintRight_toRightOf="parent" />
    
    • CHAIN_SPREAD —— 展开元素 (默认);均等分
    image.png
    • CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent;
    image.png
    • CHAIN_PACKED —— 链的元素将被打包在一起。
    image.png image

    权重:Weighted chains

    • layout_constraintHorizontal_weight
    • layout_constraintVertical_weight

    image.png
    <Button
            android:id="@+id/sbBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="xxxx"
            app:layout_constraintEnd_toStartOf="@+id/sbBtn01"
            app:layout_constraintHorizontal_weight="2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/sbBtn01"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            app:layout_constraintEnd_toStartOf="@+id/sbBtn02"
            app:layout_constraintHorizontal_weight="1"
            app:layout_constraintStart_toEndOf="@+id/sbBtn"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/sbBtn02"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="xxxxxxxxxxxxxxxxxxxx"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_weight="1"
            app:layout_constraintStart_toEndOf="@+id/sbBtn01"
            app:layout_constraintTop_toTopOf="parent" />
    

    Barrier屏障

    使用场景:假设有3个控件ABC,C在AB的右边,但是AB的宽是不固定的,这个时候C无论约束在A的右边或者B的右边都不对。当出现这种情况可以用Barrier来解决。Barrier可以在多个控件的一侧建立一个屏障,如下所示:

    image.png

    属性说明:其中,app:constraint_referenced_ids="btn_a,btn_b"这句指定这个Barrier是用来控制idbtn_a和btn_b的两个控件。而app:barrierDirection="end"这句等于在这两个控件的右端设置一道“屏障”。

    最后,我们让控件C依赖于这个Barrier。注意这句:app:layout_constraintLeft_toLeftOf="@id/barrier"

    ** app:barrierDirection="right",值有多个可调节,比如start,bottom , top**

    <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="right"
            app:constraint_referenced_ids="btn_a,btn_b" />
    
        <Button
            android:id="@+id/btn_a"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="200dp"
            android:text="这是控件A,我比较宽"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn_b"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="这是控件B"
            app:layout_constraintLeft_toLeftOf="@id/btn_a"
            app:layout_constraintTop_toBottomOf="@id/btn_a" />
    
        <Button
            android:id="@+id/btn_c"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="200dp"
            android:text="这是控件C"
            app:layout_constraintLeft_toLeftOf="@id/barrier"
            app:layout_constraintTop_toTopOf="parent" />
    
    

    Group:控制一系列id相关控件的显示隐藏状态

    在xml文件中设置 android:visibilitys属性

    androidx.constraintlayout.widget.Group中使用****app:constraint_referenced_ids="btn_a,btn_b,btn_c" 可将相关id可见属性****android:visibility="visible"****进行显示隐藏显示。

     <!--计数Group-->
        <androidx.constraintlayout.widget.Group
            android:id="@+id/count_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="visible"
            app:constraint_referenced_ids="btn_a,btn_b,btn_c" />
    
        <androidx.constraintlayout.widget.Barrier
            android:id="@+id/barrier"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:barrierDirection="right"
            app:constraint_referenced_ids="btn_a,btn_b" />
    
        <Button
            android:id="@+id/btn_a"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="200dp"
            android:text="这是控件A,我比较宽我比较宽我比较宽"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn_b"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:text="这是控件B"
            app:layout_constraintLeft_toLeftOf="@id/btn_a"
            app:layout_constraintTop_toBottomOf="@id/btn_a" />
    
        <Button
            android:id="@+id/btn_c"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_marginTop="200dp"
            android:text="这是控件C"
            app:layout_constraintLeft_toLeftOf="@id/barrier"
            app:layout_constraintTop_toTopOf="parent" />
    
         
    

    代码控制:****在代码中通过group.setVisibility()方法来设置

    但是我在实践中发现,当我在代码中调用group.setVisibility()来显示或隐藏group中的一组控件时,这个方法并没有生效。通过查看源码发现,Group更新他成员的可见性状态是在 updatePreLayout(),而这个方法最终是在ConstraintLayout中通过updateHierarchy()方法调用的

    那么我们就可以在设置可见性之后再调用group.requestLayout(),而requestLayout()方法会导致View的onMeasure、onLayout、onDraw方法被调用,这样我们就可以立即改变group中控件的可见性了。

    
    if (recIsClick) {
        countGroup.setVisibility(View.VISIBLE);
     
    } else if (recIsClick) {
        countGroup.setVisibility(View.INVISIBLE);
    }
     
    countGroup.requestLayout();
    
    

    Placeholder占位符

    Placeholder指的是占位符。在Placeholder中可使用setContent()设置另一个控件的id,使这个控件移动到占位符的位置。新建一个Placeholder约束在屏幕的左上角,新建一个TextView约束在屏幕的右上角,在Placeholder中设置 app:content="@+id/textview",这时TextView会跑到屏幕的左上角。举个例子:

    <androidx.constraintlayout.widget.Placeholder
            android:id="@+id/placeholder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:content="@+id/textview"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />
    
        <TextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#cccccc"
            android:padding="16dp"
            android:text="TextView"
            android:textColor="#000000"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />
    
    

    Guideline

    说明:Guildline像辅助线一样,在预览的时候帮助你完成布局(不会显示在界面上)。

    使用属性:

    • android:orientation 垂直vertical,水平horizontal
    • layout_constraintGuide_begin 开始位置
    • layout_constraintGuide_end 结束位置
    • layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)
       <androidx.constraintlayout.widget.Guideline
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/guideline"
            app:layout_constraintGuide_begin="250dp"
            android:orientation="vertical"/>
        <androidx.constraintlayout.widget.Guideline
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/guideline2"
            app:layout_constraintGuide_percent="0.1"
            android:orientation="vertical"/>
    
        <Button
            android:text="Button_guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button"
            android:background="#ff0000"
            app:layout_constraintLeft_toLeftOf="@+id/guideline"
            android:layout_marginTop="16dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>
       
    
    效果图: image.png

    相关文章

      网友评论

        本文标题:ConstraintLayout基本使用

        本文链接:https://www.haomeiwen.com/subject/tqzriltx.html