ConstraintLayout初识

作者: 王灵 | 来源:发表于2020-05-16 10:17 被阅读0次

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都无效了

相关文章

网友评论

    本文标题:ConstraintLayout初识

    本文链接:https://www.haomeiwen.com/subject/xgclohtx.html