美文网首页
ConstraintLayout的用法

ConstraintLayout的用法

作者: 因为我的心 | 来源:发表于2022-06-30 12:33 被阅读0次

一、前言:

因为在复杂布局,我们会一直用RelativeLayout和LinearLayout去嵌套,因为嵌套的ViewGroup会导致手机多次测量和绘制,从而影响性能,如果嵌套严重可能出现掉帧或卡顿。

使用ConstraintLayout一招入魂。一句话概括是:传统布局能实现的,它能轻松实现实现。传统布局不能实现的,它也能实现。

二、使用:

1、使用1

如图下图所示,我们分别用RelativeLayout和ConstraintLayout去实现它:


图片.png

在xml里。我们无法用RelativeLayout去实现,如下分析

  • B在A下方,通过 android:layout_below="@+id/txt_a"实现
  • B要在A底部边框上,垂直居中。那么我们要知道B的height。B再使用marginTop="-height/2"才能达到效果。所以在xml里无法实现,只能去代码里动态计算。

使用ConstraintLayout则可轻松完成:

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

    <TextView
        app:layout_constraintRight_toRightOf="@+id/txt_a"
        app:layout_constraintLeft_toLeftOf="@+id/txt_a"
        app:layout_constraintTop_toBottomOf="@+id/txt_a"
        app:layout_constraintBottom_toBottomOf="@+id/txt_a"
        android:id="@+id/txt_b"
        .../>

</androidx.constraintlayout.widget.ConstraintLayout>

2、如图:靠右边

图片.png

实现如图功能:

<TextView
    ...
    app:layout_constraintRight_toRightOf="parent"
    />

layout_constraintRight_toRightOf 属性还有left、right、top、bottom、start、end等搭配使用。什么意思呢?

  • 第一个Right代表 本控件的右边
  • 第二个Right代表 要位于目标控件右边。
  • 所以app:layout_constraintRight_toRightOf=“parent”; 红色A的右边位于父容器的右边

注意start、end是因为很多国家阅读习惯不一样,比如我们是习惯从左往右阅读。所以start对于我们来说就是left,end就是right。

3、如图:居中

图片.png

实现如图功能:

<TextView
    ...
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    />

右边和父控件右边对齐,左边和父控件左边对齐。这样就可以达到横向居中,同理竖直。

注意这里居中了。同样还可以用margin进行偏移。也可以利用属性app:layout_constraintHorizontal_bias=“0.5”,进行横向偏移,0.5意思也还算居中。同理竖直的属性。

4、如图:充满屏幕

图片.png

比如B要在A的右边,且相对A上下居中,而且B要充满剩余横屏:

<TextView
    app:layout_constraintLeft_toRightOf="@+id/txt_a"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="@+id/txt_a"
    app:layout_constraintBottom_toBottomOf="@id/txt_a"
    android:layout_width="0dp"
    ...
    />

要想充满全屏把宽度设置为0dp。然后通过以下代码:

  • app:layout_constraintLeft_toRightOf="@+id/txt_a";B的左边和A的右边对齐
  • app:layout_constraintRight_toRightOf=“parent”;B的右边和父容器的右边对齐

这样B就在A的右边,且横向充满屏。注意:在约束布局里match_parent是不生效的。

要想B竖直方向与A平行的话,通过如下代码:

  • app:layout_constraintTop_toTopOf="@+id/txt_a";B的上边和A的上边对齐
  • app:layout_constraintBottom_toBottomOf="@id/txt_a";B的下边和A的下边对齐
    这样就可以让B在A右边,上下居中。

5、如图:不嵌套居中

图片.png

在列表里我们经常会遇到这样的需求,A是一张图片,title是标题,des是描述。用RelativeLayout的做法是:继续用一个layout布局包裹title和des,居中然后放在A的右边。

用ConstraintLayout的话不用嵌套,3个view就搞定了。如下:


<ImageView
    ...
    />


<TextView
    app:layout_constraintTop_toTopOf="@+id/image"
    app:layout_constraintBottom_toTopOf="@+id/txt_des"
    android:id="@+id/txt_title"
    ...
    />

<TextView
    app:layout_constraintTop_toBottomOf="@+id/txt_title"
    app:layout_constraintBottom_toBottomOf="@+id/image"
    
   * 这个时候你会发现还没有居中因为还缺了一条约束,title在des上边;
    android:id="@+id/txt_des"
    ...
    />

为例3,已经讲过如何全屏了,这里主要讲title和des如何居中:

  • des 在title下面;app:layout_constraintTop_toBottomOf="@+id/txt_title"
  • title上边和图片A上边对齐;app:layout_constraintTop_toTopOf="@+id/image"
  • des下边和图片A下边对齐;app:layout_constraintBottom_toBottomOf="@+id/image"
  • 这个时候你会发现还没有居中因为还缺了一条约束,title在des上边; app:layout_constraintBottom_toTopOf="@+id/txt_des",这和RelativeLayout有些区别

这里还有一个属性文本基线对齐,和RelativeLayout里的 layout_alignBaseline 是一样的效果

  • app:layout_constraintBaseline_toBaselineOf="@+id/txt_a"

6、角度定位

图片.png

实现代码如下:

<TextView
    android:id="@+id/txt_a"
    ...
     />

<TextView
    app:layout_constraintCircle="@+id/txt_a";
    app:layout_constraintCircleAngle="90"
    app:layout_constraintCircleRadius="100dp"
    android:id="@+id/txt_b"
    ...
    />
  • app:layout_constraintCircle="@+id/txt_a";B相对于A角度定位
  • app:layout_constraintCircleAngle=“90”;角度定位角度为90°
  • app:layout_constraintCircleRadius=“100dp”;B中心与A中心相差100dp

7、边距

margin 值要生效,一定是伴随约束属性的。什么意思呢,要实现如图功能:

图片.png

代码实现如下:

<TextView
    android:id="@+id/txt_a"
    ...
     />

<TextView
    android:layout_marginLeft="20dp"
    app:layout_constraintLeft_toRightOf="@+id/txt_a"
    android:id="@+id/txt_b"
    ...
     />
  • 比如B左边和A的右边对齐app:layout_constraintLeft_toRightOf="@+id/txt_a",此时在B上加上margin值生效
  • 如果这个时候在A上加上android:layout_marginRight=“50dp”,是不生效的。谨记

8、goneMargin

图1如下:


图片.png

图2如下:


图片.png

解释:
1、显示A控件的时候,执行 android:layout_marginTop="50dp";
2、隐藏A控件的时候,执行 app:layout_goneMarginTop="10dp";

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <TextView
        android:id="@+id/txt_a"
        android:layout_width="@dimen/ui_dp100"
        android:layout_height="@dimen/ui_dp100"
        android:visibility="visible"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:background="#f00"
        android:text="A"
        android:gravity="center"
        android:textColor="#fff"
        android:textSize="20sp"
        />
 //意思就是当有约束的控件隐藏时,goneMargin就会生效,那么B就会距离顶部10dp。
    <TextView
        android:id="@+id/txt_b"
        android:layout_width="@dimen/ui_dp100"
        android:layout_height="@dimen/ui_dp100"
        app:layout_constraintTop_toBottomOf="@+id/txt_a"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_goneMarginTop="10dp"
        android:layout_marginTop="50dp"
        android:background="#0f0"
        android:text="B"
        android:gravity="center"
        android:textColor="#fff"
        android:textSize="20sp"
        />
    
</androidx.constraintlayout.widget.ConstraintLayout>

9、尺寸

在ConstraintLayout里,设置尺寸大小的有3个:

  • 设置固定的dp值
  • wrap_content
  • 0dp(MATCH_CONSTRAINT),前面讲过match_parent是不生效的。如果想达到match_parent的效果只能通过0dp和约束来达到。

10、layout_constraintWidth_max

  • 属性 layout_constraintWidth_max 在使用dp固定值的时候和 android:maxWidth=“100dp” 用法是一致的。
  • 但是layout_constraintWidth_max可以搭配属性 app:layout_constraintWidth_percent=“0.5” 使用,什么意思呢。

比如我们要实现红色区域占父容器宽度的一半

图片.png

实现代码如下:

<TextView
    app:layout_constraintLeft_toLeftOf="parent"
    android:layout_width="0dp"
    android:text=""
    app:layout_constraintWidth_max="wrap"
    app:layout_constraintWidth_percent="0.5"
    ...
     />

这里这样设置的时候,意思最大宽度是父容器的一半。注意这里text=""空的时候,会像图中直接展示父容器的一半,假设我们给text="A"设置上值后,如下图,那么只会展示A的宽度,但最大宽度是父容器一半。

图片.png

11、app:layout_constrainedWidth

app:layout_constrainedWidth=“true” 属性,是按约束去限制宽度,什么意思呢?我们先不加上这条属性,实现如下图效果是这样的:

图片.png

代码是这样的:

<TextView
    android:id="@+id/txt_a"
    ...
     />


<TextView
    app:layout_constraintLeft_toLeftOf="@id/txt_a"
    app:layout_constraintRight_toRightOf="@id/txt_a"
    app:layout_constraintTop_toBottomOf="@+id/txt_a"
    android:id="@+id/txt_b"
    android:layout_width="wrap_content"
    android:text="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
    ...
     />

给txt_b加上 app:layout_constrainedWidth=“true” 属性后,就会实现下面的效果:


图片.png

意思就是B的最大宽度按照A的宽度来约束,这里要注意的是,B的宽度是wrap_content。假设这里是0dp的话,那这里就另外一种情况了,意思就是B的宽度和A的宽度一样宽。

12、设置宽高比(Set size as a ratio)

<ImageView
    android:id="@+id/imageView2"
    android:layout_width="200dp"
    android:layout_height="0dp"
    android:layout_marginTop="156dp"
    android:scaleType="fitXY"
    android:src="@drawable/ic_launcher_background"
    app:layout_constraintDimensionRatio="h,16:9"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
图片.png

① 宽固定时使用(h,16:9),高固定时使用(w,16:9),代表宽高比;
② 使用dimensionRatio一个边要设置为match_constraint,一个边是固定大小

13、Barrier

图片.png

假设有3个控件A、B、C,如果我们A,B的宽度不固定,同时又希望C在A,B的右边。如果用一个布局把A,B包裹起来,然后让C在A,B右边可以实现,如果不像嵌套就要通过Barrier了,如下图

图片.png

实现代码如下:

<TextView
    android:id="@+id/txt_1"
    ...
    />

<TextView
    android:id="@+id/txt_2"
    app:layout_constraintTop_toBottomOf="@+id/txt_1"
    ...
    />

<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="txt_1,txt_2" />

<TextView
    android:id="@+id/txt_3"
    app:layout_constraintLeft_toRightOf="@+id/barrier"
    ...
    />

Barrier属性有:

  • app:barrierDirection=“right” 为屏障时,哪个方向的屏障,图中是A和B的右边
  • app:constraint_referenced_ids=“txt_1,txt_2” 为屏障引用的id,用逗号隔开

参考:https://blog.csdn.net/leol_2/article/details/123280735

相关文章

网友评论

      本文标题:ConstraintLayout的用法

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