IT@程序员猿媛Android控件我收藏的Android开发文章

ConstraintLayout简单的基础使用

2019-04-20  本文已影响38人  Android砖家

不管三七二十一,来张官方的截图

官方链接:https://developer.android.google.cn/reference/android/support/constraint/ConstraintLayout

yhx.png

官方文档说的很清楚了:ConstraintLayout是个ViewGroup,可以灵活的方式定位和调整,这句话很重要。


1.ConstraintLayout能够解决什么问题?

一句话加一说明:解决在开发过程中布局过多嵌套问题。


2.如何使用ConstraintLayout?

从androidstudio2.3起,官方模板默认就已经使用了ConstraintLayout,如果还有老铁默认不是ConstraintLayout,那就赶紧升级as吧。怪我咯!!!!!!


3.使用

相对定位

定位常用属性:

  • 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
  • layout_constraintStart_toEndOf
  • layout_constraintStart_toStartOf
  • layout_constraintEnd_toStartOf
    *layout_constraintEnd_toEndOf

app:layout_constraintLeft_toRightOf 在目标元素的右侧
    <TextView
        android:id="@+id/TextView1"
        android:layout_width="140dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView1" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="140dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toRightOf="@id/TextView1" />
yhx.png
app:layout_constraintTop_toBottomOf 在目标元素下方
  <TextView
        android:id="@+id/TextView2"
        android:layout_width="140dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView2"
        />
    <TextView
       
        android:id="@+id/TextView3"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/TextView2" />

yhx.png
app:layout_constraintLeft_toLeftOf="parent" 在父元素左边
 <TextView
        android:id="@+id/TextView3"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimaryDark"
        android:text="TextView2"
        android:gravity="center"
        app:layout_constraintLeft_toLeftOf="parent"
        />
yhx.png
app:layout_constraintRight_toRightOf="parent" 在父元素右边

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimaryDark"
        android:text="TextView2"
        android:gravity="center"
       app:layout_constraintRight_toRightOf="parent"
        />

yhx.png
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"同时使用
    <TextView
        android:id="@+id/TextView3"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

yhx.png
app:layout_constraintBaseline_toBaselineOf 文本对齐

TextView1高度为150dp
TextView2高度50dp
如果不设置app:layout_constraintBaseline_toBaselineOf 应该是这样显示的


yhx.png

设置app:layout_constraintBaseline_toBaselineOf 之后显示是这样的 ,使文本对齐了


    <TextView
        android:id="@+id/TextView1"
        android:layout_width="150dp"
        android:layout_height="100dp"
        android:background="@color/colorPrimaryDark"
        android:text="TextView2"
        android:gravity="center" />


    <TextView
        android:id="@+id/TextView2"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimaryDark"
        android:text="TextView2"
        android:layout_marginLeft="20dp"
        android:gravity="center"
         app:layout_constraintLeft_toRightOf="@id/TextView1"
        app:layout_constraintBaseline_toBaselineOf="@id/TextView1"
        />


yhx.png

角度定位

概念:就是用一个角度,和距离来约束两个物理的位置。

   <TextView
        android:id="@+id/TextView1"
        android:layout_width="150dp"
        android:layout_height="80dp"
        android:background="@color/colorPrimaryDark"
        android:text="TextView1"
        android:gravity="center" />


    <TextView
        android:id="@+id/TextView2"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimaryDark"
        android:text="TextView2"
        android:layout_marginLeft="20dp"
        android:gravity="center"
        app:layout_constraintCircle="@id/TextView1"
        app:layout_constraintCircleAngle="120"
        app:layout_constraintCircleRadius="180dp"
        />

app:layout_constraintCircle 目标位置
app:layout_constraintCircleAngle="120" 角度
app:layout_constraintCircleRadius="180dp" 距离

翻译过来就是:TextView2的中心位置在TextView1中心120度,距离为150dp处

yhx.png

边距 margin

ConstraintLayout的边距常用属性如下:

  • android:layout_marginStart
  • android:layout_marginEnd
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom

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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimaryDark"
        android:gravity="center"
        android:text="TextView2"
        />

</android.support.constraint.ConstraintLayout>
yhx.png

发现我设置了android:layout_marginLeft="20dp" android:layout_marginTop="20dp"竟然没有效果, 在ConstraintLayout 里面要实现margin ,必须先约束该控件在ConstraintLayout 中的位置,如下如

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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimaryDark"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

特别注意: 1。直接给TextView1 设置 android:layout_marginLeft="20dp" 和 android:layout_marginTop="20dp" 单独在ConstraintLayout里面不生效的。 2。必须要给TextView1 约束一个相对位置。

yhx.png
goneMargin的使用

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

  • layout_goneMarginStart
  • layout_goneMarginEnd
  • layout_goneMarginLeft
  • layout_goneMarginTop
  • layout_goneMarginRight
  • layout_goneMarginBottom
layout_goneMarginLeft 举例说明
<?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">

<TextView
    android:id="@+id/TextView1"
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:layout_marginLeft="20dp"
    android:layout_marginTop="20dp"
    android:background="@color/colorPrimaryDark"
    android:gravity="center"
    android:text="TextView2" />

<TextView
    android:id="@+id/TextView2"
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:background="@color/colorAccent"
    android:gravity="center"
    android:text="TextView2"
    app:layout_goneMarginLeft="20dp"
    app:layout_constraintLeft_toRightOf="@id/TextView1" />

</android.support.constraint.ConstraintLayout>

当我把TextView2 设置 app:layout_goneMarginLeft="20dp" ,把TextView1 分别 设置android:visibility="gone",和TextView1 设置 android:visibility="visible" 前后对比效果

yhx.png

当我把TextView1设置gone时,TextView2的app:layout_goneMarginLeft="20dp"就生效了


居中和偏移

在RelativeLayout,常用 android:layout_centerHorizontal="true" android:layout_centerVertical="true",使控件在父布局中水平居中,或者垂直居中。

在ConstraintLayout 使用

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
<?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">

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="150dp"
        android:layout_height="50dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:background="@color/colorPrimaryDark"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>
水平居中.png

当把TextView1 设置为水平时,还可以设置android:layout_marginLeft="30dp"

水平居中并且设置margin之后.png

当把TextView1设置属性app:layout_constraintHorizontal_bias="0.3"时


水平居中并且设置app:layout_constraintHorizontal_bias之后.png

注意:app:layout_constraintHorizontal_bias 取值范围为0-1,为0时,显示在布局最左侧,为1时,显示在布局最右侧,为0.5时,居中显示

app:layout_constraintVertical_bias=""同理可证,忽略了,约束的方向则变成了上和下即可。


尺寸约束

官方不推荐在ConstraintLayout中使用match_parent,可以设置 0dp

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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="0dp"
        android:layout_height="45dp"
        android:layout_marginLeft="60dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

TextView1宽度设为0dp,左右两边约束parent的左右两边,并设置左边边距为60dp

yhx.png
设置宽高比

当宽或高至少有一个尺寸被设置为0dp时,可以通过属性
layout_constraintDimensionRatio来设置宽高比

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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintDimensionRatio="1:1"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toLeftOf="parent"
         />

</android.support.constraint.ConstraintLayout>

yhx.png

注意:app:layout_constraintDimensionRatio不能单独使用 ,需要给该控件约束位置,例如给该控制设置app:layout_constraintLeft_toLeftOf="parent" 配合 app:layout_constraintDimensionRatio="1:1" 才有效果


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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/TextView2" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintLeft_toRightOf="@id/TextView1"
        app:layout_constraintRight_toLeftOf="@id/TextView3" />

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView3"
        app:layout_constraintLeft_toRightOf="@id/TextView2"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

3个TextView相互约束,两端两个TextView分别与parent约束,成为一条链

yhx.png

看这效果图:就是等分啊

一条链的第一个控件是这条链的链头,我们可以在链头中设置
layout_constraintHorizontal_chainStyle来改变整条链的样式。chains提供了3种样式,分别是:
spread—— 展开元素 (默认);
spread_inside—— 展开元素,链的两端贴近parent;
packed—— 链的元素将被打包在一起。
如图所示:

yhx.png

当把3个TextView 的layout_width 设置为0dp时


yhx.png

当把layout_width 设置为0dp时,配合layout_constraintHorizontal_weight(constraintVertical为纵向)使用,又就是权重链

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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorAccent"
        android:gravity="center"
        android:text="TextView1"
        app:layout_constraintHorizontal_chainStyle="spread_inside"
        app:layout_constraintHorizontal_weight="2"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/TextView2" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimaryDark"
        android:gravity="center"
        android:text="TextView2"
        app:layout_constraintHorizontal_weight="4"
        app:layout_constraintLeft_toRightOf="@id/TextView1"
        app:layout_constraintRight_toLeftOf="@id/TextView3" />

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="TextView3"
        app:layout_constraintHorizontal_weight="4"
        app:layout_constraintLeft_toRightOf="@id/TextView2"
        app:layout_constraintRight_toRightOf="parent" />

</android.support.constraint.ConstraintLayout>

权重链.png

Barrier使用

yhx.png

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

yhx.png
<?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">

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:text="AAA"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        android:text="BBBBB"
        android:textSize="30dp"
       app:layout_constraintTop_toBottomOf="@id/TextView1" />

    <android.support.constraint.Barrier
        android:id="@+id/barrier"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="right"
        app:constraint_referenced_ids="TextView1,TextView2" />

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:text="CCCCCCC"
        android:textSize="30dp"
       app:layout_constraintLeft_toRightOf="@+id/barrier"/>


</android.support.constraint.ConstraintLayout>

app:constraint_referenced_ids : 目标控件,可以设置多个(用,隔开)
app:barrierDirection : 位置 bottom ,end , left , right ,start ,top

yhx.png

Group

作用:顾名思义就是一个控件组,就是把多个控件放在一个篮子里。

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

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:text="AAA"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        android:text="BBBBB"
        android:textSize="30dp"
        app:layout_constraintTop_toBottomOf="@id/TextView1" />


    <TextView
        android:id="@+id/TextView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:text="CCCCCCC"
        android:textSize="30dp"
        app:layout_constraintTop_toBottomOf="@id/TextView2" />

    <android.support.constraint.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="invisible"
        app:constraint_referenced_ids="TextView1,TextView3" />


</android.support.constraint.ConstraintLayout>

yhx.png

可以设置android:visibility="invisible" 和android:visibility="gone"都是可以的
app:constraint_referenced_ids :目标控件id

Placeholder 占位符

在Placeholder中可使用setContent()设置另一个控件的id,使这个控件移动到占位符的位置


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


    <android.support.constraint.Placeholder
        android:id="@+id/placeholder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:content="@id/TextView1"
        app:layout_constraintLeft_toLeftOf="parent" />

    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:text="默认右边"
        android:textSize="30dp"
        app:layout_constraintRight_toRightOf="parent" />


</android.support.constraint.ConstraintLayout>

从上面的代码可以看出 新建Placeholder 在屏幕的左边 ,新建TextView1在屏幕右边,当设置Placeholder 属性android:text="TextView1"时,TextView1就会显示在Placeholder 占位符的里面

yhx.png

Guideline使用

Guildline可以看做是辅助线,在预览的时候帮助你完成布局(不会显示在界面上)。
Guildline的属性:
android:orientation 垂直vertical,水平horizontal
layout_constraintGuide_begin 开始位置
layout_constraintGuide_end 结束位置
layout_constraintGuide_percent 距离顶部的百分比(orientation = horizontal时则为距离左边)

设置app:layout_constraintGuide_begin="50dp
<?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">


    <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:background="@color/colorPrimary"
        android:text="AAAAAA"
        android:textSize="30dp" />

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

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:background="@color/colorPrimary"
        android:gravity="center"
        android:text="设置app:layout_constraintGuide_begin=50dp"
        android:textColor="@color/colorAccent"
        app:layout_constraintTop_toBottomOf="@id/guideline" />


</android.support.constraint.ConstraintLayout>

当设置app:layout_constraintGuide_begin=50dp时,可以从下图可以看出它的起始位置为屏幕顶部开始。下面有白色间隙,是因为TextView1设置的高度为45dp ,为了把这种效果看的更清楚一点。

yhx.png
设置app:layout_constraintGuide_end=50dp

当设置app:layout_constraintGuide_end=50dp时,可以从下图可以看出它的起始位置为屏幕底部开始。下面有白色间隙,是因为TextView1设置的高度为45dp ,为了把这种效果看的更清楚一点。

yhx.png
设置app:layout_constraintGuide_percent=0.5

注意app:layout_constraintGuide_percent的取值为0-1

yhx.png

好了,到此为止,ConstraintLayout 基础使用差不多就介绍完了,使用ConstraintLayout 可以看出在布局方面确实可以减少多层嵌套

上一篇下一篇

猜你喜欢

热点阅读