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