ConstraintLayout

控件尺寸

1.固定大小
2.使用wrap_content,可以通过android:minWidth 最小的宽度
android:minHeight 最小的高度
android:maxWidth 最大的宽度
android:maxHeight 最大的高度
注意!当ConstraintLayout为1.1版本以下时,使用这些属性需要加上强制约束,如下所示:
app:constrainedWidth=”true”
app:constrainedHeight=”true”
3.使用0dp;官方不推荐在ConstraintLayout中使用match_parent
4.宽高比;
当宽或高至少有一个尺寸被设置为0dp时,可以通过属性layout_constraintDimensionRatio设置宽高比
在设置宽高比的值的时候,还可以在前面加W或H,分别指定宽度或高度限制。 例如:
app:layout_constraintDimensionRatio="H,2:3"指的是 高:宽=2:3
app:layout_constraintDimensionRatio="W,2:3"指的是 宽:高=2:3
不写HW,默认为W
5.百分比:
当宽或高设置为0dp且其与约束控件全重叠(如与parent,LeftToLeft,RightTorRight)则可以设置
app:layout_constraintWidth(Height)_default="percent"
app:layout_constraintWidth(Height)_percent="0.3"
来控制大小

控件与父容器相对位置

<?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"
    tools:context=".MainActivity">
<!-- 左上-->
    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="左上"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:background="#ff00ff"
        />
<!-- 右上-->
    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="右上"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#ff00ff"
        />
<!-- 左下-->
    <TextView
        android:id="@+id/text3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="左下"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:background="#ff00ff"
        />
<!-- 右下-->
    <TextView
        android:id="@+id/text4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="右下"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#ff00ff"
        />

<!-- 居中或者全屏,哪个属性设置wrap_content或xxdp则居中,设置0dp,match_parent则全屏-->
    <TextView
        android:id="@+id/text5"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Text5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#00ffff"
        />
<!-- 居中长度按比例,设置0dp, 长度按比例-->
   <TextView
        android:id="@+id/text5_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Text51"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#00ffff"
        app:layout_constraintWidth_percent="0.3"
       app:layout_constraintWidth_default="percent"
        />

<!-- 右下-->
    <TextView
        android:id="@+id/text6"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:text="Text6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#ffff00"
        />
<!-- 类居中偏移-->
<!-- 属性设置为固定长度除0dp外或者wrap_content;则可用bias来按比例偏移。若是全屏则bias无效;
bias赋一个范围为 0-1 的值,假如赋值为0,则TextView1在布局的最左侧,假如赋值为1,则TextView1在布局的最右侧,假如假如赋值为0.5,则水平居中,假如假如赋值为0.3,则更倾向于左侧
-->
 <TextView
        android:id="@+id/text7"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Text7"
        app:layout_constraintHorizontal_bias="0.1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:background="#00ffff"
    />
<!-- 无论控件居中、按比例居中还是全屏margin设置的偏移值都有效-->
 <TextView
        android:id="@+id/text8"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="Text8"
        app:layout_constraintHorizontal_bias="0.1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginLeft="10dp"
        android:layout_maringRight="20dp"
        android:background="#00ffff"
    />
</androidx.constraintlayout.widget.ConstraintLayout>

控件与控件相对位置

1.与控件与父控件相同:另一控件居中,全重叠,左上、右上,左下,右下对齐
2.控件还可以在控件左边(上中下),右边(上中下),上边(左中右),下边(左中右 )
3.如果控件是TextView,还可以通过设置layout_constraintBaseline_toBaselineOf以文本基线对齐
4.角度定位
app:layout_constraintCircle="@+id/TextView1"
app:layout_constraintCircleAngle="120"(角度)
app:layout_constraintCircleRadius="150dp"(距离)
指的是TextView2的中心在TextView1的中心的120度,距离为150dp
角度为顺时针,12点方向为0度。

goneMargin

goneMargin主要用于约束的控件可见性被设置为gone的时候使用的margin值,属性如下:
layout_goneMarginStart
layout_goneMarginEnd
layout_goneMarginLeft
layout_goneMarginTop
layout_goneMarginRight
layout_goneMarginBottom
可以理解为:约束对象的对象为gone,则其以goneMarginXXX值来替代

实现链:形成链的作一控件都设有左右关联(如果是垂直链则是上下关联),最左或最右则与parent
事例代码如:

 <TextView
        android:id="@+id/TextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/TextView2" />

    <TextView
        android:id="@+id/TextView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/TextView1"
        app:layout_constraintRight_toLeftOf="@+id/TextView3"
        />

    <TextView
        android:id="@+id/TextView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/TextView2"
        app:layout_constraintRight_toRightOf="parent" />

1.链式可以在首个控件设置链的样式:

水平链Key:layout_constraintHorizontal(Vertical)_chainStyle
样式值:
CHAIN_SPREAD —— 展开元素 (默认);
CHAIN_SPREAD_INSIDE —— 展开元素,但链的两端贴近parent;
CHAIN_PACKED —— 链的元素将被打包在一起。

2.权重链(可以理解为替代LinearLayout的权重)

将要设置填充的控件width/height设置为0dp,然后设置layout_constraintHorizontal(constraintVertical)_weight来占有,如果有多个设置此值,点按点比来。此方与LinearLayout相同,只是没有LinearLayout的父值的weightSum(其实也不需要)

Group

在布局文件中加入Group控件androidx.constraintlayout.widget.Group;然后app:constraint_referenced_ids设置要归为一组(以","分割),然后通过控制Group来控制整组的显示隐藏

屏障(barrier)

有时需要将一个控件置于多个控件的最一边比如如下,C想置A,B的最右边,但A,B的长度不一定,而如果设置为A的右侧或设置为B的右侧都不合适。可以在增加barrier控件,并设置为A,B的右侧屏障
A...End
C....
B.........End

<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="Aid,Bid" />

<TextView
        android:id="@+id/C"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@+id/barrier" />

占位符(Placeholder)

Placeholder控件可以用来做为占位符,在需要的时候可以指定(app:content=id)需要移动此此占位符位置的控件

Guideline

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

优化(Optimizer)

将控件设置为0dp,ConstraintLayout 将对控件进行 2 次测量
在ConstraintLayout上设置layout_optimizationLevel系统会根据布局做一些优化(?);可通过 |添加以下多个:
barriers:找出屏障所在,并用简单的约束取代它们
direct:优化那些直接连接到固定元素的元素,例如屏幕边缘或引导线,并继续优化直接连接到它们的任何元素。
standard:这是包含 barriers 和 direct 的默认优化级别。
dimensions:目前处于实验阶段,并且可能会在某些布局上出现问题——它会通过计算维度来优化布局传递。
chains:目前正在实验阶段,并计算出如何布置固定尺寸的元素链。

ConstraintSet

1.修改ConstraintLayout子元素

示例1:

 ConstraintSet set= new ConstraintSet(); 
 //获取一新的ConstraintLayout
 //mConstraintLayout 是你的当前使用的约束布局
set.clone(mConstraintLayout);
//这里是重新设置边距,当然也可以重新设置这个view的任何约束,  参数2的类型,可以点进入方法内部,看源码。
set.setMargin(R.id.id, 1,Utils.dip2px(20)); 
set.setMargin(R.id.id, 3,imageTopMare+Utils.dip2px(20));
//最后一步就是设置新的ConstraintLayout约束 这个必须设置;
set.applyTo(mConstraintLayout);

示例2:

ConstraintSet set = new ConstraintSet();
set.clone(constraintLayout);
// 或 
// set.clone(this, R.layout.main_activity);

set.connect(v1.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM);
set.connect(v2.getId(), ConstraintSet.TOP, v1.getId(), ConstraintSet.BOTTOM, dp2px(16));
set.applyTo(constraintLayout);

注意:
1.当使用ConstraintSet 的时候,你的约束布局里面的所有子view,都必须有个id,不然就会报错 All children of ConstraintLayout must have ids to use ConstraintSet
2.如果有View的隐藏显示操作,务必显示操作View.setVisibility(View.VISIBLE)不要在1、2步中间执行,因为建立约束时,之前的位置约束将可能被改变,从而显示可能失效。

2.实现动画

 ConstraintSet mConstraintSet1 = new ConstraintSet(); // create a Constraint Set
    ConstraintSet mConstraintSet2 = new ConstraintSet(); // create a Constraint Set

mConstraintSet2.clone(context, R.layout.state2); // get constraints from layout
        setContentView(R.layout.state1);
        mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);
        mConstraintSet1.clone(mConstraintLayout);

public void foo(View view) {
        TransitionManager.beginDelayedTransition(mConstraintLayout);
        if (mOld = !mOld) {
            mConstraintSet1.applyTo(mConstraintLayout); // set new constraints
        }  else {
            mConstraintSet2.applyTo(mConstraintLayout); // set new constraints
        }
    }

注意:两个布局的控件的id要一样,不一样则不一样的控件不会生效

约束布局ConstraintLayout看这一篇就够了
ConstraintLayout+ConstraintSet实现动画效果
ConstraintLayout约束布局使用ConstraintSet修改某个子view

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345