ConstraintLayout约束布局详解

前言: 

ConstraintLayout 约束布局,由 2016 年 Google I/O 推出。为了解决布局嵌套和模仿前端flexible布局的一个新布局。减少布局的层级,优化渲染性能。它集 LinearLayout(线性布局),RelativeLayout(相对布局),百分比布局等的功能于一身,功能强大,使用灵活。

Google官方推荐所有操作都在”Design”区域搞定,即通过可视化拖拖拽拽生成布局大致的样子,然后针对具体属性、约束 精细修改。 一个不可不会的布局神器:

目录:

margin_left和margin_start区别:

相对定位 (Relative positioning)

解除关联(layout_goneMargin)

居中定位和倾向(Centering positioning and bias)

尺寸约束(Dimensions constraints)

宽高比例(Ratio)

链条(Chains)_仿flexible

辅助布局(Guideline)

0.1:

在写layout布局的时候,我们会发现有这样几个比较相似的属性:
MarginStart   MarginLeft

MarginEnd    MarginRight

这些属性的区别是什么?  根据api注释,我们得知MarginStart指的是控件距离开头View部分的间距大小,MarginLeft则指的是控件距离左边View部分的间距大小,MarginEnd和MarginRight同理。

       一般情况下,View开始部分就是左边,但是有的语言目前为止还是按照从右往左的顺序来书写的,例如阿拉伯语,在Android  4.2系统之后,Google在Android中引入了RTL布局,更好了支持了由右到左文字布局的显示,为了更好的兼容RTL布局,google推荐使用MarginStart和MarginEnd来替代MarginLeft和MarginRight,这样应用可以在正常的屏幕和由右到左显示文字的屏幕上都保持一致的用户体验。

1.内部元素居左,居右,垂直居中,水平居中,垂直水平居中。

主要是Top_toTopOf="parent",Bottom_toBottomOf="parent",Right_toRightOf="parent",Left_toLeftOf="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=".ConstrainLayoutUI">
    <android.support.constraint.ConstraintLayout
        android:id="@+id/cs"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="@color/colorAccent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/A"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="28dp"
            android:text="A"
            app:layout_constraintBaseline_toBaselineOf="@+id/B"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/B"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="B"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/C"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="居左"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <Button
            android:id="@+id/D"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="居右"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

        <Button
            android:id="@+id/E"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="垂直水平居中"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />
        <Button
            android:id="@+id/F"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="垂直居中"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent" />
        <Button
            android:id="@+id/G"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="水平居中"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />
    </android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

app:layout_goneMarginRight属性:

虽然button4与button5的marginRight居右(具有相互依赖关系,彼此影响),但layout_goneMarginRight可以在button4消息时解除与button5的依赖关系(button4的消失不会影响button5的位置)

<Button
        android:id="@+id/button4"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="button4"
        app:layout_constraintRight_toRightOf="parent"
        />

    <!-- android:layout_marginRight="10dp" 
    配合 app:layout_goneMarginRight="110dp"一起使用,
    在约束的布局gone时,起用goneMargin,
    但是一定要预先设置对应方向上的margin -->
    <Button
        android:id="@+id/button5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="10dp"
        android:text="button5"
        app:layout_constraintRight_toLeftOf="@id/button4"
        app:layout_goneMarginRight="110dp"/>

倾向(Bias)
搭配bias,能使约束偏向某一边,默认是0.5,有以下属性: 
* layout_constraintHorizontal_bias (0最左边 1最右边) 
* layout_constraintVertical_bias (0最上边 1 最底边)

比如上个Demo,我加入app:layout_constraintHorizontal_bias="0.9" ,则会在水平方向上向右偏移至90%。


控件尺寸约束(Widgets dimension constraints)

     

<Button
        android:id="@+id/button11"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toLeftOf="@+id/button10"
        app:layout_constraintRight_toRightOf="@+id/button10"
        app:layout_constraintTop_toBottomOf="@+id/button10"/>

这里的android:layout_width="0dp"

0dp等于MATCH_CONSTRAINT应该是撑满屏幕的呀,但它match的是约束。 
而这里第三个按钮的约束是第二个按钮,是和它的约束按钮,即第二个按钮一样宽。 

android:layout_height="wrap_content",不能将其设为0,因为竖直方向上没有约束

比例:

<Button
        android:layout_width="200dp"
        android:layout_height="0dp"
        android:text="Ratio"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="2:1"
        app:layout_constraintTop_toTopOf="parent"/>

宽高比为:1/2

 <Button
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,2:1"
        app:layout_constraintTop_toTopOf="parent"/>


/*
可以在比率值的前面添加 W 或者 H 来分别约束宽度或者高度。

这里用“H”表示以高度为约束,高度的最大尺寸就是父控件的高度,“2:1”表示高:宽 = 2 : 1. 
则宽度为高度的一半:

//

链条布局:

取值如下: 
* spread - 元素将被展开(默认样式) 
* 加权链 - 在spread模式下,如果某些小部件设置为MATCH_CONSTRAINT,则它们将拆分可用空间 
* spread_inside - 类似,但链的端点将不会扩展 
* packed - 链的元素将被打包在一起。 孩子的水平或垂直偏差属性将影响包装元素的定位

拿加权链举个例子:   

 <Button
        android:id="@+id/buttonA"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="50dp"
        android:text="Button"
        app:layout_constraintHorizontal_chainStyle="spread"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/buttonB"/>

    <Button
        android:id="@+id/buttonB"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintLeft_toRightOf="@+id/buttonA"
        app:layout_constraintRight_toRightOf="parent"/>

Guideline
Guideline只能用于ConstraintLayout中,是一个工具类,不会被显示,仅仅用于辅助布局。 
它可以是horizontal或者 vertical的。(例如:android:orientation="vertical") 
* vertical的Guideline宽度为零,高度为ConstraintLayout的高度 
* horizontal的Guideline高度为零,宽度为ConstraintLayout的高度
 

主要参考自大神文章https://blog.csdn.net/zxt0601/article/details/72683379/

猜你喜欢

转载自blog.csdn.net/qq_41063141/article/details/83047986