Android ConstraintLayout布局

在学习控件的使用之前,了解下布局的相关知识是十分必要的。今天就来看看ConstraintLayout布局。

ConstraintLayout是Android Studio 2.2中主要的新增功能之一,ConstraintLayout是使用可视化的方式来编写界面。它的出现主要是为了解决布局嵌套过多的问题,以灵活的方式定位和调整小部件。

约束布局ConstraintLayout 是一个ViewGroup,可以在Api9以上的Android系统使用。ConstraintLayout是采用约束的方式来指定各个控件的位置和关系的。

关键听说阿里都让使用这玩意。。。。。。

在项目中使用ConstraintLayout

首先,我们的确认在我们项目的build.gradle文件中是否添加了google存储仓库,对于使用高一点版本的Android Studio来说这一点不需要担心。。

在这里插入图片描述

下一步在我们app的build.gradle文件中添加ConstraintLayout依赖,这一步新一点的版本我们也不需要去手动添加。。。不放心的可以确认下。

现在ConstraintLayout在我们创建布局文件的时候已经是默认的布局了。可想这些事我们都不需要操心了。

在这里插入图片描述

如果上面两个你检查完了,发现得自己添加的话,那么再多做一件事情吧。

点解"Sync Project with Gradle Files"进行一下同步吧.

好了,新建一个空的Activity,并勾选生成布局文件选项,看看出来的布局文件:

在这里插入图片描述

编写布局可以拖也可以写,这里选择手写xml布局文件。习惯了还是觉得写的来的快,勿喷。。。

使用相对定位(Relative positioning)

相对定位是我们在ConstraintLayout布局中很基础的一种使用姿势了,使用相对定位允许我们将给定的控件相对于另一个控件进行定位。常见的使用姿势是:控件给定一侧限制为任何其他控件的另一侧。

看个示意图:

在这里插入图片描述

那么该如何设置呢?

语法格式示例: app:layout_constraintLeft_toRightOf="控件id"
如果目标控件为父控件则id可以直接写成parent,否则写控件的id。

在上面的布局文件中添加一个Button,不做任何布局约束。

在这里插入图片描述

可用的约束:

layout_constraintLeft_toLeftOf: 当前控件的Left在目标控件的Left上
layout_constraintLeft_toRightOf: 当前控件的Left在目标控件的Right上
layout_constraintRight_toLeftOf: 当前控件的Right在目标控件的Left上
layout_constraintRight_toRightOf: 当前控件的Right在目标控件的Right上
layout_constraintTop_toTopOf: 当前控件的Top在目标控件的Top上
layout_constraintTop_toBottomOf: 当前控件的Top在目标控件的Bottom上
layout_constraintBottom_toTopOf: 当前控件的Bottom在目标控件的Top上
layout_constraintBottom_toBottomOf: 当前控件的Bottom在目标控件的Bottom上
layout_constraintBaseline_toBaselineOf:当前控件的Baseline在目标控件的Baseline上
layout_constraintStart_toEndOf: 当前控件的Start在目标控件的End上
layout_constraintStart_toStartOf: 当前控件的Star在目标控件的Star上
layout_constraintEnd_toStartOf: 当前控件的End在目标控件的Start上
layout_constraintEnd_toEndOf: 当前控件的End在目标控件的End上

上下左右就不多说了,都明白啥意思,start和end这里给张示意图大家脑部一下:
在这里插入图片描述

首先我们添加一个Button,让其位于屏幕中央位置:

 <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="屏幕居中">
    </Button>

在这里插入图片描述
当然我们也可以使用left,right来实现水平居方向的约束:

`
<Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="屏幕居中">
    </Button>

在添加两个Button:

  <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/btn1"
        app:layout_constraintBottom_toTopOf="@+id/btn1"
        android:text="按钮2">
    </Button>

    <Button
        android:id="@+id/btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toLeftOf="@+id/btn1"
        app:layout_constraintTop_toBottomOf="@+id/btn1"
        android:text="按钮3">
    </Button>

在这里插入图片描述

使用Margins

可用列表:

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

我们修改下布局文件:

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginBottom="100dp"
        android:text="按钮1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

在这里插入图片描述

注意:margin属性需要配合约束来设置,比如你设置了左边的约束,那么你就可以使用android:layout_marginStart和android:layout_marginLeft,否则不会生效。

看个例子:

 <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="50dp"
        android:text="按钮1"
        app:layout_constraintEnd_toStartOf="@+id/btn2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        ></Button>

    <Button
        android:id="@+id/btn2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="20dp"
        android:text="按钮2"
        app:layout_constraintStart_toEndOf="@+id/btn1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

运行结果:
在这里插入图片描述
这里去掉右边和btn2的约束,大家再看下效果:

//app:layout_constraintEnd_toStartOf="@+id/btn2"

在这里插入图片描述
总之就是一句话,控件和谁有约束,在哪个方向的约束那么就可以在哪个方向设置Margin。

这里还有一种情况,那就是我们添加约束的目标控件在某些场合需要隐藏(即设置属性为GONE)的时候,我们可指定控件相对于其他控件的边距。此时需要使用下面的属性:

layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom

看个例子:

 <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮2"
        app:layout_constraintStart_toEndOf="@+id/btn1"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_goneMarginLeft="20dp"></Button>

    <Button
        android:id="@+id/btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮3"
        app:layout_constraintStart_toEndOf="@id/btn2"
        app:layout_constraintTop_toTopOf="parent"></Button>

这里摆放了三个在一行的按钮:
在这里插入图片描述
将按钮1的visibility设置为gone

android:visibility="gone"

此时按钮2左边的约束就相对于是parent了,那么此时按钮2应该距离左边20dp:
在这里插入图片描述
当然了,实际的使用比这复杂的多, 这里只希望通过这样的例子能大概明白是怎么用的,到了实际使用的时候能够快速入手。

Bias

首先我们看个例子:

      <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"></Button>

有如上设置的button,那么这个button到底是怎么在屏幕显示的呢?

我刚开始以为是这个样子的:
在这里插入图片描述
我们想一下start与parent左侧对其,end与parent右侧对其,那不是相当于设置为match_parent吗?可实际上我们给按钮的宽度设定是wrap_content,也就是说button是没有办法向两边撑开的。显然这个猜测是不正确的。

那么如果我们把layout_width设为0dp,是不是就能 达到这样的效果呢?验证之后发现果然是的。

官方文档的解释是:当给控件在水平方向添加相反的约束(当然了是针对同一个target)时,constraintlayout布局会将控件显示在target宽度的中间。就像两个相反的力一样,使控件两边的空白相同。

对于上面的例子来说,就是将按钮1居中显示:
在这里插入图片描述

遇到上面的情况,我们可能希望按钮靠左边显示,此时我们就需要借助Bias属性来进行控制。

可选值:

layout_constraintHorizontal_bias //水平方向偏移
layout_constraintVertical_bias // 垂直方向偏移

这两个值得取值范围时:0 ~ 1,默认为0.5,即居中。不在这个范围的话,在屏幕中无法显示出来。

为按钮1添加水平方向的偏移,方向时从左到右。

 app:layout_constraintHorizontal_bias="0"

将值设置为0,意味着我们的控件将在水平方向的左边开始位置开始显示。

在这里插入图片描述
那么设置为1的时候,自然就在最右边了。
在这里插入图片描述

设置为0.3:

在这里插入图片描述

垂直方向就不再演示了,效果一样的。

Circular positioning

这个该怎么翻译呢,直译的话就是圆形定位。官方给出的解释大概意思是这样的;

我们可以相对于一个控件的中心位置,以一定的角度和半径来约束目标控件的中心位置。

所以我还是将之称呼为圆心定位算了,不喜勿怪,英语水平有限。。。

看张示意图:

在这里插入图片描述

简单来说就是使用圆心定位进行约束,那么目标控件的中心点一定在以该控件中心,半径为n的圆角度为m的位置处。

可用属性:

layout_constraintCircle :目标控件id
layout_constraintCircleRadius : 圆半径
layout_constraintCircleAngle : 角度 (取值: 0 ~ 360)

看个实例:

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按钮1"
        app:layout_constraintCircle="@+id/btn1"
        app:layout_constraintCircleAngle="90"
        app:layout_constraintCircleRadius="100dp" />

这里我们指定半径为100dp,然后角度为90度,也就是和按钮1的中心点平齐。

在这里插入图片描述

Dimensions constraints

尺寸约束,这里针对的是对ConstraintLayout布局本身,注意:这些最小和最大尺寸将在ConstraintLayout的尺寸设置为WRAP_CONTENT时使用。

可用参数;

android:minWidth
android:minHeight
android:maxWidth
android:maxHeight

看个例子:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@color/colorPrimaryDark"
    tools:context=".QConstraintLayout">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:minWidth="200dp"
        android:minHeight="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:background="@color/colorPrimaryDark"
            />


    </androidx.constraintlayout.widget.ConstraintLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
实际上这些属性在将尺寸设置为match_parent的时候同样可用,不过存在布局显示差异,有兴趣的朋友可以试试。

Widgets dimension constraints:控件尺寸约束

我们可通过以下3种不同方式设置android:layout_width和android:layout_height属性值指定控件的尺寸。

使用指定数值
使用wrap_content
使用0dp,相当于match_constraint

不建议对ConstraintLayout中包含的控件使用MATCH_PARENT。

如果我们在指定 wrap_content属性的情况下,还想对控件进行特别的约束,那么可以使用下面的属性进行设置:

app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”

这里在说一下当设置layout_width或者layout_height为0dp的时候,默认行为是使结果大小占用所有可用空间。注意只有两边都存在约束的时候才能看到效果哦。

示例:

    <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimaryDark"
            android:text="测试1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            android:text="测试22"
            app:layout_constraintStart_toEndOf="@+id/btn1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

运行效果:
在这里插入图片描述

如果我们去掉右边的约束:

app:layout_constraintEnd_toEndOf="parent"

在这里插入图片描述
看到这里大家应该清楚该怎么用了吧。。。要想有效果至少我的有一个宽度和高度让我去适应吧。。

Ratio

简单点就是百分比布局。

使用前提是:ayout_width或者layout_height至少有一个设置为0dp。

属性:

layout_constraintDimensionRatio

可选值:

浮点值,表示宽度和高度之间的比率
“宽度:高度”形式的比率,添加H约束高度,添加W约束宽度。

示例:

  <Button
        android:id="@+id/btn1"
        android:layout_width="150dp"
        android:layout_height="0dp"
        android:background="@color/colorPrimaryDark"
        android:text="测试1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,1:3"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="150dp"
        android:layout_height="0dp"
        android:background="@color/colorAccent"
        android:text="测试22"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="W,1:3"
        app:layout_constraintTop_toTopOf="@+id/btn1" />

效果图:

在这里插入图片描述

Chains

在横轴或或者竖轴上的控件相互约束时,可以组成一个链式约束。链在单个轴(水平或垂直)上提供类似行的行为。另一个轴可以独立约束。

在这里插入图片描述

如果一组控件通过双向连接链接在一起,则它们被视为链。链由链的第一个元素(链的“头部”)上设置的属性控制.链头是水平链的最左侧控件,垂直链的最顶部控件。

这里是引用

可用属性:

app:layout_constraintHorizontal_chainStyle
app:layout_constraintVertical_chainStyle

可选值:

spread模式:元素将展开(默认样式);
spread_inside模式: 类似spread模式,但链的端点不会分散;
含有权重spread模式:如果设置了某个或某些控件MATCH_CONSTRAINT(0dp),这个或这些控件将分割可用空间;
packed模式:链条的元素将被包装在一起。然后,子项的水平或垂直偏差属性将影响打包元素的定位;

下图是各种取值的表现形式。

在这里插入图片描述

在这里插入图片描述

具体示例就贴出来了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章