API好像说明的很清晰 API
ConstraintLayout局如其名,主要在于约束。要定位一个view的位置必须先有约束条件;
定位的两种方式:XY定位和圆形定位
-
XY定位
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
...
ConstraintLayout的约束有非常多,但是XY定位的约束很好理解
app:layout_constraint[我的哪条边]_to[与那条边有关系]Of="[与之关联的view]"
解读app:layout_constraintBottom_toBottomOf="parent"
我的下边需要与parent(父view)的下边进行约束
居中
居中是ConstraintLayout非常厉害的一个优势,写法非常简单;指定两条边就可以了;如下
//水平局中
app:layout_constraintStart_toStartOf="@id/view"
app:layout_constraintEnd_toEndOf="@id/view"
//垂直局中
app:layout_constraintTop_toTopOf="@id/view"
app:layout_constraintBottom_toBottomOf="@id/view"
很好理解,就是取指定的两条边的中心点,然后让我的中心与之重合。
那么下面这个怎么实现的呢?
偷了高老师的图.png
上面说了,居中实际上中心点与中心点(是线的中心点,不是面。莫要钻牛角尖)的重合,而我们的要求是什么? 1、毛左右居中 2、相对大图的下边居中
//左右居中
app:layout_constraintStart_toStartOf="@id/view"
app:layout_constraintEnd_toEndOf="@id/view"
//相对下边居中
app:layout_constraintTop_toBottomOf="@id/view"//注意Top_toBottom
app:layout_constraintBottom_toBottomOf="@id/view"
相信你懂了~
基准线对齐
有一个比较特殊的使用场景,文字的基准线对其
app:layout_constraintBaseline_toBaselineOf
="@+id/text_view"
-
圆形定位
这是一个之前都没有过的体验 哈哈哈
app:layout_constraintCircle="@id/view" //圆心
app:layout_constraintCircleAngle="90"//角度 12点方向为0度 顺时针
app:layout_constraintCircleRadius="180dp"//圆心
特殊用法
-
约束限制
限制控件大小不会超过约束范围。
app:layout_constrainedWidth="true"
app:layout_constrainedHeight="true
-
偏向
上面介绍了要定位必须设置约束,但是如果同时设置上下约束就会被居中,那么如果不想居中怎么办?设置偏向
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
控制控件在垂直方向的 30%的位置(百分比 0.0~1.0)
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.3"
<!--app:layout_constraintHorizontal_bias="0.3"-->
-
约束链
在约束链上的第一个控件上加上 chainStyle ,用来改变一组控件的布局方式
- packed(打包)
- spread (扩散)
- spread_inside(内部扩散)
//垂直方向 packed
app:layout_constraintVertical_chainStyle="packed"
-
权重
权重作为线性布局的一大特征,ConstraintLayout也有。使用方法类似
android:layout_width="0dp"
app:layout_constraintHorizontal_weight="2"
-
填充
在之前我们如果需要让子view铺满父view我们会使用match_parent
,现在依然可以,这里要说的是ConstraintLayout支持的另外一种写法
android:layout_width="0dp"
-
宽高比
新东西哦
android:layout_width="100dp"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:2"
-
百分比
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.5"
辅助工具
-
GuideLine
在使用之前需要指定方向
android:orientation="vertical"
指定位置的方式有三种,如果同时存在优先级 percent>begin>end
app:layout_constraintGuide_begin="100dp"//距离开始位置100dp
app:layout_constraintGuide_end="100dp"//距离结束位置100dp
app:layout_constraintGuide_percent="0.13"//优先级高于上面 ;在13%的位置
-
Group
通过 constraint_referenced_ids
使用引用的方式来避免布局嵌套。
可以为一组控件统一设置 setVisibility
这个比较常用,其它->API
group.visibility=View.VISIBLE
继承自ConstraintHelper。实现方式:ConstraintHelper.applyLayoutFeatures
里for循环一个个设置的
-
Layer
2.0才添加的 API
和 Group 类似,同样通过引用的方式来避免布局嵌套,可以为一组控件统一设置旋 转/缩放/ 位移。
layer.translationX=100.dp
layer.translationY=100.dp
layer.rotation=45f
如果添加了多个View,旋转的时候会很奇怪,看上去像是对View添加了一个父View包裹然后对父View的旋转。然而不是的:通过 区域中心点(mComputedCenterX,mComputedCenterY) 、View中心点(x,y)、 角度(mGroupRotateAngle)计算除了偏移量.通过对每个view设置不同的xy偏移来实现了整体旋转的视觉效果
private void transform() {
if (this.mContainer != null) {
if (this.mViews == null) {
this.reCacheViews();
}
this.calcCenters();
double rad = Math.toRadians((double)this.mGroupRotateAngle);
float sin = (float)Math.sin(rad);
float cos = (float)Math.cos(rad);
float m11 = this.mScaleX * cos;
float m12 = -this.mScaleY * sin;
float m21 = this.mScaleX * sin;
float m22 = this.mScaleY * cos;
for(int i = 0; i < this.mCount; ++i) {
View view = this.mViews[i];
int x = (view.getLeft() + view.getRight()) / 2;
int y = (view.getTop() + view.getBottom()) / 2;
float dx = (float)x - this.mComputedCenterX;
float dy = (float)y - this.mComputedCenterY;
float shiftx = m11 * dx + m12 * dy - dx + this.mShiftX;
float shifty = m21 * dx + m22 * dy - dy + this.mShiftY;
view.setTranslationX(shiftx);
view.setTranslationY(shifty);
view.setScaleY(this.mScaleY);
view.setScaleX(this.mScaleX);
view.setRotation(this.mGroupRotateAngle);
}
}
}
-
Barrier
通过设置一组控件的某个方向的屏障
计算一系列view的极值
<androidx.constraintlayout.widget.Barrier
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"//计算最右边的坐标
app:constraint_referenced_ids="view1,view3"/>
-
Placeholder
当在占位符上设置另一个视图的ID(使用setContentId(id))时,该占位符有效地成为内容视图。如果内容视图存在于屏幕上,则将其视为已离开其原始位置。
-
Flow
流虚拟布局,API
1. 关联view
老操作
app:constraint_referenced_ids="v1,v2,v3,v4"
2. app:flow_wrapMode="none/chain/aligned"
没搞懂,从实际出发介绍下
- none
这将简单地从引用的小部件中创建一个水平或垂直链。这是Flow的默认行为
不会换行
android:orientation="vertical"//设置方向
app:flow_verticalGap="10dp"//纵向上的元素间距 使用场景自己斟酌
app:flow_verticalStyle="packed/spread/spread_inside"//链样式
- chain
会自动换行
app:flow_firstHorizontalStyle="spread_inside"//单独设置第一个链的样式
app:flow_firstHorizontalBias="0.2"//只有一个时的位置偏移
app:flow_lastHorizontalBias="0.1"//只有一个时的位置偏移
app:flow_lastHorizontalStyle="spread_inside"单独设置最后一个链的样式
- aligned
会自动对齐
first和last都无效了
网友评论