原文链接。
MAD 技术:Compose 布局 和 修饰符 第 3 集
在 上一篇 MAD 技术文章 中,您了解了将数据转换为 UI 的 Compose 的三个阶段。咱们创立了一个 思维模型 来协助咱们推理 app 的规划实现。在这一集中,咱们将运用该思维模型来学习推理 修饰符链 以及它是怎么影响咱们的可组合项的巨细的。
您也能够将本文作为 MAD 技术视频观看: youtu.be/OeC5jMV342A
还记得上一集咱们有 三个阶段 将数据转换为 UI 吗:
- 组合: 显现什么
- 布局: 放在哪儿
- 制作: 怎么渲染
修饰符能够影响不同的阶段。例如,size
和 padding
修饰符在布局阶段影响可组合项的巨细和间距,而 clip
修饰符在制作阶段影响可组合项的形状:
咱们还知道,咱们能够向可组合项增加多个修饰符,然后 创立一个链条。但是,这些链中的不同修饰符是怎么相互影响的,却并不总是清楚明了。
自己试试
让咱们从一些操练开端。对以下每个代码片段,请尝试找出 哪个选项将是履行该片段的成果,选项 A 或 B:
问题 1
/* Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
Image(
painterResource(R.drawable.frag),
contentDescription = null,
Modifier
.fillMaxSize()
.size(50.dp)
)
问题 2
/* Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
Image(
painterResource(R.drawable.frag),
contentDescription = null,
Modifier
.fillMaxSize()
.wrapContentSize()
.size(50.dp)
)
问题 3
/* Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
Image(
painterResource(R.drawable.frag),
contentDescription = null,
Modifier
.clip(CircleShape)
.padding(10.dp)
.size(100.dp)
)
不能确认答案?那你来对地方了!持续阅读来了解更多信息。(往这儿看,答案就在博文结尾)
束缚
要了解怎么推理修饰符次序,咱们有必要了解布局阶段 Constraints
的效果。
还记得吗,在上一篇文章中咱们讨论了布局阶段怎么遵从 三步算法 找到每个布局节点的宽度、高度和 x、y 坐标:
- 丈量子节点: 一个节点丈量它的子节点,假如有的话。
- 决议本身巨细: 基于这些丈量,节点将决议本身巨细。
- 放置子节点: 每个子节点都相对于节点本身的方位放置。
在此算法的前两个步骤中,束缚有助于 为咱们的节点找到合适的巨细。它们是节点宽度和高度的 最小和最大鸿沟。当节点决议它的巨细时,它的丈量巨细应该落在这个给定的巨细范围内。
在算法的第一步中,束缚在 UI 树中 从父级传递给子级。当父节点丈量其子节点时,它会向每个子节点供给这些束缚,让他们知道答应的巨细。然后,当它决议自己的巨细时,它也会恪守由自己的父级们传入的束缚。
束缚的类型
束缚能够是 有界的,表明最小和最大的宽度和高度:
有界的束缚
束缚也能够是 无界的,在这种情况下节点不受任何巨细的束缚。 然后将最大的宽度和高度鸿沟设置为无穷大:
无界的束缚
又或许束缚也能够是 准确的,要求节点遵从准确的巨细要求。最小和最大的鸿沟设置为相同的值:
准确的束缚
当然,这些的组合也是有用的,例如限制宽度,同时答应无限制的最大高度,或许设置准确宽度但供给有界高度:
有界的、无界的 和 准确的 宽度和高度的组合
演练算法
要了解束缚怎么从父级传递给子级,以及怎么依据这些束缚解析巨细,最好 看一个例子。不管怎样,这在视频格式中都更简单出现,所以我建议您 观看 MAD 技术视频的“示例”一章:
youtu.be/OeC5jMV342A
修饰符及其对束缚的影响
经过观看视频,您应该很好地了解 束缚怎么影响可组合项的巨细,以及 修饰符怎么影响这些束缚。 在本节中,咱们将仔细研讨一些特定的修饰符以及它们是怎么影响束缚的。
size
修饰符
让咱们看看下面的 UI 树,它应该在 300dp 乘 200dp 的容器中出现。束缚是 有界的,答应宽度在 100dp
和 300dp
之间,高度在 100dp
和 200dp
之间。
size
修饰符 调整传入的束缚以匹配传递给它的值,例如 150dp
:
但是,假如 恳求的尺度太小或太大 怎么办?也就是说,假如宽度和高度小于最小束缚鸿沟,或许大于最大束缚鸿沟怎么办?
在这种情况下,修饰符将尝试 尽可能挨近地匹配传递的束缚,同时仍然恪守传入的束缚:
这也解说了为什么 链接多个size
修饰符不起效果。 第一个 size
修饰符会将最小和最大束缚设置为固定值,即便第二个 size
修饰符恳求更小或更大的巨细,它仍然需求恪守传入的确切鸿沟,因而它不会掩盖这些值:
requiredSize 修饰符
假如您的确需求您的节点 掩盖传入的束缚,您能够将 size
修饰符替换为另一个名为 requiredSize
的修饰符。 它将替换传入的束缚并传递您指定的巨细,作为准确鸿沟。 然后,当巨细被传递回树时,子节点将在可用空间中居中:
width 和 height 修饰符
在前面的示例中,咱们运用了 size
修饰符,它能够习惯束缚的宽度和高度。但是,咱们也能够将它们替换为 width
修饰符,设置一个 固定的宽度,但保存不决的高度。或许咱们能够运用 height
修饰符,它设置了一个 固定的高度,但保存不决的宽度:
sizeIn 修饰符
假如您需求对束缚进行细粒度控制,并希望 依据您的详细需求调整它们,您能够运用 sizeIn
修饰符:
操练的答案
已然咱们了解了束缚以及它们怎么影响丈量,那让咱们回到咱们开端的用例并找到正确的解决方案。
问题 1
/* Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
Image(
painterResource(R.drawable.frag),
contentDescription = null,
Modifier
.fillMaxSize()
.size(50.dp)
)
这是解决方案:
-
fillMaxSize
修饰符更改束缚以将最小宽度和高度都设置为最大值 – 宽度为300dp
,高度为200dp
。 - 因而,即便
size
修饰符想要运用 50dp 的巨细,它仍然需求恪守传入的最小束缚。因而,巨细修饰符还将输出300
乘以200
的准确束缚鸿沟,有用地 疏忽size
修饰符中供给的 值。 -
Image
遵从这些鸿沟并(向上)陈述巨细为300
乘以200
,这个巨细将一直向上传递。
问题 2
/* Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
Image(
painterResource(R.drawable.frag),
contentDescription = null,
Modifier
.fillMaxSize()
.wrapContentSize()
.size(50.dp)
)
这是解决方案:
-
fillMaxSize
修饰符的行为仍然相同,并调整束缚以将最小宽度和高度都设置为最大值 – 宽度为300dp
,高度为200dp
。 -
wrapContentSize
修饰符重置最小束缚。 因而,虽然fillMaxSize
导致固定束缚,但wrapContentSize
将其重置回有界束缚。下面的节点现在能够再次占据整个空间,或许小于整个空间。 -
size
修饰符将束缚设置为50
的最小和最大边界。 -
Image
解析为50
乘50
的巨细,并且size
修饰符将其转发。 -
wrapContentSize
修饰符有一个特殊的属性。它承受它的子项,并 将它放在 传递给它的 可用最小鸿沟的中心。因而,它与父级通信的巨细等于传递给它的最小边界。
经过组合仅仅三个修饰符,咱们就能够为咱们的可组合项界说一个尺度,并将其居中于其父级!
问题 3
/* Copyright 2023 Google LLC.
SPDX-License-Identifier: Apache-2.0 */
Image(
painterResource(R.drawable.frag),
contentDescription = null,
Modifier
.clip(CircleShape)
.padding(10.dp)
.size(100.dp)
)
这是解决方案:
-
clip
修饰符不会更改束缚。 -
padding
修饰符降低了最大束缚。 -
size
修饰符将所有束缚设置为100dp
。 -
Image
恪守这些束缚并陈述巨细为100
乘以100dp
。 -
padding
修饰符在所有尺度上增加10dp
,因而它会将陈述的宽度和高度增加20dp
。 - 现在,在制作阶段,
clip
修饰符效果于120
乘120dp
的画布。因而它 创立了一个该巨细的圆形蒙版。 -
padding
修饰符然后在所有尺度上以10dp
刺进其内容,因而它把画布尺度降低到了100
乘100dp
。 - 然后在该画布中制作
Image
。你能够看到图像是依据本来的120dp
圆进行裁剪的,因而咱们看到了非圆的成果。
总结
哇,今天内容真不少!您了解了 束缚,并运用它们来推理修饰符、怎么对其进行排序以及丈量。
在下一篇文章中,咱们将向您展示怎么运用这些信息来开端实现 您自己的自界说布局。
这篇博文是系列博文的一部分:
第 1 集:Compose 布局 和 修饰符 的基础知识
第 2 集:Compose 的各个阶段
第 3 集:束缚 和 修饰符 次序
第 4 集:高级布局概念