首页 > 其他分享 >ConstraintLayout约束布局使用全解

ConstraintLayout约束布局使用全解

时间:2022-11-29 18:39:00浏览次数:41  
标签:控件 layout app 约束 ConstraintSet 全解 android ConstraintLayout view


文章目录

  • ​​目的​​
  • ​​居中​​
  • ​​居中于⽗容器​​
  • ​​居中于控件中⼼​​
  • ​​⽔平⽅向居中​​
  • ​​垂直⽅向居中​​
  • ​​居中于控件的边​​
  • ​​填充​​
  • ​​权重​​
  • ​​⽂字基准线对⻬​​
  • ​​圆形定位​​
  • ​​特殊属性​​
  • ​​约束限制​​
  • ​​偏向​​
  • ​​约束链​​
  • ​​宽⾼⽐​​
  • ​​百分⽐布局​​
  • ​​辅助控件**GuideLine**​​
  • ​​Group​​
  • ​​Layer​​
  • ​​Barrier​​
  • ​​ConstraintHelper​​
  • ​​Placeholder​​
  • ​​**Flow**​​
  • ​​自定义一个简单linearLayout​​
  • ​​ConstraintSet​​
  • ​​布局扁平化更加容易做过渡动画​​

目的

为何:布局扁平化,减少布局层级,即提高性能;

约束布局 默认需要一个垂直方向和水平方向的约束;

约束布局中的宽高的0dp含义:充满约束

宽高:match_constraint:充满父容器约束

居中

居中于⽗容器

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"

居中于控件中⼼

⽔平⽅向居中

app:layout_constraintStart_toStartOf="@id/view"
app:layout_constraintEnd_toEndOf="@id/view"

垂直⽅向居中

app:layout_constraintTop_toTopOf="@id/view"
app:layout_constraintBottom_toBottomOf="@id/view"

居中于控件的边

控件垂直居中于 view 的「下边」

app:layout_constraintTop_toBottomOf="@id/view"
app:layout_constraintBottom_toBottomOf="@id/view"

填充

⽔平⽅向填充⽗容器(通过 ​​match_constraint​​ )

app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="0dp"

备注:在早期版本中 match_parent 没有效果。

权重

为⽔平⽅向的控件设置权重,⼤⼩为 2:1:1 。

<!-- (view-1) -->
android:layout_width="0dp"
app:layout_constraintHorizontal_weight="2"

<!-- (view-2) -->
android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"

<!-- (view-3) -->
android:layout_width="0dp"
app:layout_constraintHorizontal_weight="1"

⽂字基准线对⻬

app:layout_constraintBaseline_toBaselineOf

圆形定位

通过「圆⼼」「⻆度」「半径」设置圆形定位

app:layout_constraintCircle="@id/view"
app:layout_constraintCircleAngle="90"
app:layout_constraintCircleRadius="180dp"

特殊属性

约束限制

限制控件⼤⼩不会超过约束范围。

app:layout_constrainedWidth="true"
app:layout_constrainedHeight="true

偏向

控制控件在垂直⽅向的 30%的位置

app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.3"

除了配合百分⽐定位,还有⽤于配合有时在「约束限制」的条件下不需要居中效果

的情况

垂直⽅向居顶部

app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constrainedHeight="true"
app:layout_constraintVertical_bias="0.0"

约束链

在约束链上的第⼀个控件上加上 ​​chainStyle​​ ,⽤来改变⼀组控件的布局⽅式

  • packed(打包)
  • spread (扩散)
  • spread_inside(内部扩散)

垂直⽅向 packed

app:layout_constraintVertical_chainStyle="packed"

宽⾼⽐

  • ⾄少需要⼀个⽅向的值为 ​​match_constraint​
  • 默认的都是「宽⾼⽐」,然后根据另外⼀条边和⽐例算出match_constraint 的值

宽高比,宽高都是0dp,即充满父约束指定高是计算出来的:

android:layout_height = "0dp"
android:layout_width = "0dp"
app:layout_constraintDimensionRatio = "H,2:1"

百分⽐布局

-需要对应⽅向上的值为 match_constraint

-百分⽐是 parent 的百分⽐,⽽不是约束区域的百分⽐

宽度是⽗容器的 30%

android:layout_width="0dp"
app:layout_constraintWidth_percent="0.3"

辅助控件GuideLine

  • 设置辅助线的⽅向 android:orientation=“vertical”
  • 设置辅助线的位置,根据⽅向不同:

距离左侧或上侧的距离 layout_constraintGuide_begin

距离右侧或下侧的距离 layout_constraintGuide_end

百分⽐ layout_constraintGuide_percent

Group

通过 constraint_referenced_ids 使⽤引⽤的⽅式来避免布局嵌套。

可以为⼀组控件统⼀设置 setVisibility

只有设置可⻅度的功能,不要指望这个来通知设置点击事件…

Layer

和 Group 类似,同样通过引⽤的⽅式来避免布局嵌套,可以为⼀组控件统⼀设置旋

转/缩放/ 位移。

Barrier

通过设置⼀组控件的某个⽅向的屏障,来 避免布局嵌套 。

<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android: layout_width="wrap_content"
android: layout_height="wrap_content"
app: barrierDirection="end"
app: constraint_referenced_ids="viewl, view2"/>

ConstraintHelper

example:用声明写动画

import android.view.ViewAnimationUtils
import androidx.constraintlayout.widget.ConstraintHelper
import androidx.constraintlayout.widget.ConstraintLayout
import kotlin.math.hypot

class CircularRevealHelper(context: Context, attrs: AttributeSet) : ConstraintHelper(context, attrs) {
override fun updatePostLayout (container: ConstraintLayout) {
super.updatePostLayout (container)

referencedIds.forEach {
val view = container.getViewById(it)
val radius = hypot (view.width.toDouble(), view.height.toDouble()).toInt ()
ViewAnimationUtils.createCircularReveal(view, centerX: 0, centerY: 0, startRadius: Of, radius.toFloat())
.setDuration(2000L)
.start()
}
}
}
<androidx.constraintlayout.widget.ConstraintLayout
...
>
...

<com.hencoder.CircularRevealHelper
android: layout _width="wrap_content"
android: layout_height="wrap_content"
app:constraint_referenced_ ids="image1, image2, image3, image4"
/>

</androidx.constraintlayout.widget.ConstraintLayout>

Placeholder

通过 setContentId 来将指定控件放到占位符的位置。

findViewById<Pfaceholder>(R.id.placeholder).setContentId(view.id)

Flow

通过引⽤的⽅式来避免布局嵌套。

wrapMode

  • chain
  • aligned
  • none(默认)

注意这个控件是可以被测量的,所以对应⽅向上的值可能需要被确定(即不能只约束同⼀⽅ 向的单个约束)

<androidx. constraintlayout.helper.widget.Flow
android: id="@+id/flow"
android: layout width="Odp"
android: layout_height="wrap_content"
android: layout _marginStart="16dp"
android: layout_marginTop="16dp"I
android: background="@color/colorAccent"
android:orientation="horizontal"
app: flow wrapMode="chain"
app: flow verticalGap="16dp" //竖直间距
app: flow_horizontalGap="16dp"//水平间距
app: constraint_referenced_ids="viewl, view2, view3, view4"
app: layout_constraintStart_toStartOf="parent"
app: layout_constraintTop_toTopOf="parent"/>

自定义一个简单linearLayout

class Linear (context: Context, attrs: AttributeSet) : VirtualLayout (context, attrs) {

private val constraintSet: ConstraintSet by lazy {
ConstraintSet().apply { this: ConstraintSet
isForceld = false
}

override fun updatePreLayout (container: ConstraintLayout) {
super.updatePreLayout (container)
constraintSet.clone(container)

val viewIds : IntArray! = referencedIds;
for (i: Int in 1 until mCount) {

val current: Int = viewIds[i]
val before : Int = viewIds[i - 1]
constraintSet. connect (current, ConstraintSet.START, before, ConstraintSet.START)
constraintSet.connect (current, ConstraintSet.TOP, before, ConstraintSet.BOTTOM)
constraintSet.applyTo(container)
}
}
}

ConstraintSet

使⽤ ConstraintSet 对象来动态修改布局。通过 ConstraintSet#clone 来从 xml 布局中获取约束集。

val constraintLayout = view as ConstraintLayout
val constraintSet = ConstraintSet ().apply { this: ConstraintSet
clone (constraintLayout)
connect (
R.id.twitter,
ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID,
ConstraintSet.BOTTOM
)
}
constraintSet.applyTo(constraintLayout)

防⽌布局中有⽆ id 控件时报错,需要设置 isForceId = false

布局扁平化更加容易做过渡动画

在布局修改(constraintSet)之前加上 TransitionManager 来⾃动完成过渡动画。

constraintSet如果采用代码的方式编写,较为复杂,可以写两个xml布局,一个动画之前的,一个动画之后的,再用clone,将constraintSet吸出来,加以动画即可:

TransitionManager.beginDelayedTransition(constraintLayout)


标签:控件,layout,app,约束,ConstraintSet,全解,android,ConstraintLayout,view
From: https://blog.51cto.com/u_12853553/5896494

相关文章

  • 23.大促期间网络编程与安全解读【双元】(2)
             ......
  • 列的完整性约束
    这是联合主键,因为主键只能有一个。     ......
  • xml_约束_dtd以及schema
    xml_约束_dtdDTD:一种简单的约束技术引入dtd文档到xml文档中内部dtd:将约束规则定义在xml文档中外部dtd:将约束的规则定义在外部的dtd文件中......
  • xml_组成部分以及约束概念
    xml_组成部分组成部分:1.文档声明格式:<?xml属性列表"?>属性列表version:版本号必须属性encoding:编码方式,告知解析引擎......
  • where 子句用于指定类型约束
    where子句用于指定类型约束,这些约束可以作为泛型声明中定义的类型参数的变量。   1.接口约束。        例如,可以声明一个泛型类MyGenericClass,这样,类型......
  • where 泛型类型约束 default 关键字
    首先我们来看一下泛型的基本概念:     最显著的一点就是它参数化了类型,把类型作为参数抽象出来,从而使我们在实际的运用当中能够更好的实现代码的重复利用,同时它提......
  • SQL的六种约束
    1.notnull非空约束 ①强制列不接受空值 ②例:创建表时,namevarchar(6)notnull,2.unique唯一性约束 ①约束唯一标识数据库表中的每条记录 ②unique和primarykey......
  • 表约束条件 非空 默认值 唯一 主键 自增 外键的三种关系
    ·目录无符号unsigned零填充zerofill非空notnull添加表数据的方法字段默认可以为空给字段设置非空默认值default默认值配合非空使用唯一值unique单列唯一联合唯一......
  • 字段之约束条件
    字段之约束条件MySQL字段之约束条件无符号、零填充1.unsignedcreatetablet6(idtinyintunsigned);#取消正负号insertintot6values(-129),(128),(1000);2.z......
  • 字段的约束条件
    字段的约束条件约束的作用:对表中的数据进行限制。保证数据的正确性有效性和完整性一个表如果添加了约束,不正确的数据将无法再插入到表中,约束在创建表的时候添加比较......