我知道material 3中的TopAppBarLeft/right padding of 16dp.然而,我想知道在源代码中的哪里定义的?例如,TopAppBar构造函数如下所示--没有对默认的左/右填充的提示.

@ExperimentalMaterial3Api
@Composable
fun TopAppBar(
    title: @Composable () -> Unit,
    modifier: Modifier = Modifier,
    navigationIcon: @Composable () -> Unit = {},
    actions: @Composable RowScope.() -> Unit = {},
    windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
    colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors(),
    scrollBehavior: TopAppBarScrollBehavior? = null
) {
    SingleRowTopAppBar(
        modifier = modifier,
        title = title,
        titleTextStyle = MaterialTheme.typography.fromToken(TopAppBarSmallTokens.HeadlineFont),
        centeredTitle = false,
        navigationIcon = navigationIcon,
        actions = actions,
        windowInsets = windowInsets,
        colors = colors,
        scrollBehavior = scrollBehavior
    )
}

有没有什么常量可以用来将这个填充应用到其他组件,或者我必须硬编码16dp?我希望TopAppBar以下的东西有相同的左/右填充,否则看起来不一致.

推荐答案

它在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应用于您(父)可合成的(这应该是更简单的选项),或者需要通过调用calculateLeftPaddingcalculateRightPadding来将windowInsets添加到基于LayoutDirection的正确一侧的计算中.

val ld = LocalLayoutDirection.current
val insets = windowInsets.asPaddingValues(LocalDensity.current)
val leftPadding = insets.calculateLeftPadding(ld)
val rightPadding = insets.calculateRightPadding(ld)

Android相关问答推荐

Jetpack DataStore原生lib已添加到Bundle 包:libdatastore_share_counter.so-那是什么?

如何将Hilt添加到Android Studio中的Kotlin项目中?

KMM项目生成错误-';在项目';中找不到测试类:共享';

Jetpack Compose中的导航找不到NavHost类的名称为:startDestination";的参数

登录方法显示为空列表,即使它显示的是Firebase身份验证控制台

如何隐藏OutlinedTextField边框上的提示标签

在java android studio项目上安装mapbox

FFmpeg Android 错误

如何在一个活动中预加载图像然后在另一个活动中加载它们?

在Android RoomDB中使用Kotlin Flow和删除数据时如何解决错误?

在 Jetpack Compose 中使用 ViewModel 实现 startActivity 的最佳实践

如何在 JetpackCompose 的 LazyColumn 中 Select 多个项目

Jetpack Compose Material3 禁用 ListItem

无法解析依赖项'com.github.smarteist:autoimageslider:1.4.0-appcompat'

Jetpack Compose:对角拆分卡片并将内容放入其中

如何在 TextInputEdit 中调整可绘制对象的大小

使 Compose LazyColumn 的最后一项填满屏幕的其余部分

将生成的 AAR 与 Composables 一起使用时未解决的参考

Android Java Keystore 在另一台机器上损坏

Android Jetpack Compose:如何让文本利用完整的行空间并将单词换行以防溢出?