它在TopAppBarLayout
可组合的内部、titlePlaceable.placeRelative
部分内的调用链的更下方进行定义.
以下是相关代码部分
Box(
Modifier
.layoutId("navigationIcon")
.padding(start = TopAppBarHorizontalPadding) // <-- line of interest
) {
CompositionLocalProvider(
LocalContentColor provides navigationIconContentColor,
content = navigationIcon
)
}
Box(
Modifier
.layoutId("title")
.padding(horizontal = TopAppBarHorizontalPadding) // <-- line of interest
// ...
) {
ProvideTextStyle(value = titleTextStyle) {
CompositionLocalProvider(
LocalContentColor provides titleContentColor.copy(alpha = titleAlpha),
content = title
)
}
}
layout(constraints.maxWidth, layoutHeight) {
// Navigation icon
navigationIconPlaceable.placeRelative(
x = 0,
y = (layoutHeight - navigationIconPlaceable.height) / 2
)
// Title
titlePlaceable.placeRelative(
x = when (titleHorizontalArrangement) {
Arrangement.Center -> (constraints.maxWidth - titlePlaceable.width) / 2
Arrangement.End ->
constraints.maxWidth - titlePlaceable.width - actionIconsPlaceable.width
// Arrangement.Start.
// An TopAppBarTitleInset will make sure the title is offset in case the
// navigation icon is missing.
else -> max(TopAppBarTitleInset.roundToPx(), navigationIconPlaceable.width)
},
// ...
这是上面的代码中使用的值
private val TopAppBarHorizontalPadding = 4.dp
private val TopAppBarTitleInset = 16.dp - TopAppBarHorizontalPadding
它们被定义为库的一部分,因此它们基本上是常量,不太可能在不同版本之间更改.即使它们发生更改,您也可以控制何时更新库,并且在这一点上,您还可以更新您的填充以再次匹配.
因此,当顶部应用程序栏没有显示导航图标时,start
侧的填充是12.dp
,然后是标题Box
,标题Box
有自己的填充4.dp
,总共有16.dp
个填充.
并且当顶栏确实显示导航图标时,start
侧的填充是0.dp
,然后跟随导航图标Box
,导航图标Box
具有其自己的填充4.dp
,总共填充4.dp
.
然而,导航图标通常是通过使用IconButton
并将Icon
作为内容添加到其中来添加的.IconButton
的最小(touch )大小是48.dp
(在IconButton
可组合的内部定义),默认的Icon
大小是24.dp
.这意味着,即使实际填充是4.dp,但Icon
边上的"视觉"填充是4.dp + (48.dp / 2 - 24.dp / 2) = 4.dp + 12.dp
=16.dp
.
在动作图标所在的end
侧或标题结束的位置(没有动作图标时),情况类似.
因此,在这两种情况下(只要您使用的是默认图标大小),"视觉"填充在16.dp
处是相同的.因此,如果您决定将内容填充为16.dp
,布局将看起来是对齐的.
请注意,所有这些都假设左/右windowInsets
为0,这可能不是所有设备和所有方向的情况.
因此,为了确保布局在所有情况下都是对齐的,您还需要在布局中考虑windowInsets
.如果你已经这样做了,那么当你添加16.dp
个填充物时,事情应该正确地对齐.如果不是,则需要将windowInsets
应用于您(父)可合成的(这应该是更简单的选项),或者需要通过调用calculateLeftPadding
和calculateRightPadding
来将windowInsets
添加到基于LayoutDirection
的正确一侧的计算中.
val ld = LocalLayoutDirection.current
val insets = windowInsets.asPaddingValues(LocalDensity.current)
val leftPadding = insets.calculateLeftPadding(ld)
val rightPadding = insets.calculateRightPadding(ld)