Android 约束布局(ConstraintLayout)1,最详细的解释小白也能听懂
app:layout_constraintCircleRadius="30dp" />
</android.support.constraint.ConstraintLayout>
运行结果:
Enforcing constraints
在 1.1 版本之前,如果将控件的尺寸设置为了 WRAP_CONTENT,那么对控件设置约束(如:minWidth 等)是不起作用的。那么强制约束(Enforcing constraints)的作用就是,在控件被设置 WRAP_CONTENT 的情况下,使约束依然生效。
需要使用到的属性有:
app:constrainedWidth="true|false"
app:constrainedHeight="true|false"
下面的例子演示了没有设置强制约束和设置了强制约束的对比:
<ImageViewandroid:id="@+id/img_avatar"android:layout_width="wrap_content"android:layout_he
ight="wrap_content"android:src="@mipmap/ic_avatar"app:layout_constrainedWidth="false"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_max="100dp" />
<ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/ic_avatar"app:layout_constrainedWidth="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@id/img_avatar"app:layout_constraintWidth_max="100dp" />
运行结果:
Dimensions
1.1 版本中,当控件的尺寸设置为了 MATCH_CONSTRAINT 时( 0dp),在设置尺寸上又多了二个新的修饰属性:
layout_constrainWidth_percent。
layout_constrainHeight_percent。
这两个属性的作用就是指定当前控件的宽度或高度是父控件的百分之多少。可设置的值在 0 - 1 之间,1 就是 100%。
设置头像的宽度占父控件宽度的 80%(父控件占满全屏)例子:
<ImageViewandroid:id="@+id/img_avatar"android:layout_width="0dp"android:layout_height="wrap_content"android:scaleType="centerCrop"android:src="@mipmap/ic_avatar"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintWidth_percent="0.8" />
运行结果:
Margins and chains
在 1.1.0-beta4 版本中(已知),为链中的控件设置 marginRight/End 是无效的(个人感觉这应该是个 Bug)。而在 1.1 稳定版中,无论设置右边距还是左边距都是有效果的,会累计计算。并且在计算剩余空间时,会将边距一起考虑。
Optimizer
需要知道的是,当我们使用 MATCH_CONSTRAINT 时,ConstraintLayout 将不得不对控件进行 2 次测量,而测量的操作是昂贵的。
而优化器(Optimizer)的作用就是对 ConstraintLayout 进行优化,对应设置给 ConstraintLauyout 的属性是:
layout_optimizationLevel。
可设置的值有:
none:不应用优化。
standard:仅优化直接约束和屏障约束(默认的)。
direct:优化直接约束。
barrier:优化屏障约束。
chain:优化链约束(实验)。
dimensions:优化尺寸测量(实验)。
在设置值时,可以设置多个,如:
app:layout_optimizationLevel="direct|barrier|dimensions"
Barrier
当我们在布局时,有时候就会遇到布局会随着数据的多少而改变大小的情况。以下图为例:
(图片来自官方)
通过上图就可以发现,当在 A、B 控件的大小都不确定的情况下, View3 以谁作为约束对象都不对。如果以 A 作为约束对象,那么当 B 的宽度过宽时就会被遮挡,同理以 B 作为约束也是如此。
那么此时,Barrier(屏障)就派上用场了。这是个非常好用的东东,和 GuideLine 一样,它是一个虚拟的 View,对界面是不可见的。目的就是辅助布局。
对 Barrier 可以使用的属性有:
barrierDirection:设置 Barrier 所创建的位置。可设置的有:bottom、end、left、right、start、top。
constraint_referenced_ids:设置 Barrier 引用的控件。可设置多个,设置的方式是:id, id。(无需加 @id/)
barrierAllowsGoneWidgets:默认为 true,即当 Barrier 引用的控件被 GONE 掉时,则 Barrier 默认的创建行为是在已 GONE 掉控件的已解析位置上进行创建。如果设置为 false,则不会将 GONE 掉的控件考虑在内。
说再多不如看代码,还是以上图为例,来看看 Barrier 是如何解决的:
<?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"android:padding="16dp"tools:context="com.github.airsaid.constraintlayoutdemo.MainActivity">
<TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Title"android:textSize="16sp"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" />
<TextViewandroid:id="@+id/desc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="This is a descriptive text."app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/title" />
<android.support.constraint.Barrierandroid:id="@+id/barrier"android:layout_width="match_parent"android:layout_height="match_parent"app:barrierDirection="end"app:constraint_referenced_ids="title, desc" />
<TextViewandroid:id="@+id/content"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="This is a piece of content that is very long and long very long and long ..."app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toEndOf="@id/barrier"app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
运行结果:
评论