Jetpack Compose 中的 sp 大小与 XML sp 大小不同吗?

aku*_*ubi 7 android android-xml android-jetpack-compose

这可能是一个奇怪的问题,但是spJetpack Compose 中的定义与spXML 中的定义不同吗?我们使用的 XML 样式TextView定义如下:

    <style name="Body">
        <item name="android:textSize">12sp</item>
        <item name="android:lineSpacingExtra">8dp</item>
        <item name="android:letterSpacing">-0.03125</item>
    </style>
Run Code Online (Sandbox Code Playgroud)

android:fontFamily我们还有一个在 XML 中定义的字体系列,并通过和应用于主题fontFamily

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">

    <font
        app:font="@font/some_font_regular"
        app:fontStyle="normal"
        app:fontWeight="500" />

    <font
        app:font="@font/some_font_italic"
        app:fontStyle="italic"
        app:fontWeight="500" />

    <font
        app:font="@font/some_font_bold"
        app:fontStyle="normal"
        app:fontWeight="700" />

    <font
        app:font="@font/cera_pro_bold_italic"
        app:fontStyle="italic"
        app:fontWeight="700" />

</font-family>
Run Code Online (Sandbox Code Playgroud)

转到 Jetpack Compose,我们有一个数据类,其中包含TextStyles字体系列的定义,我们尝试在其中模仿 XML 中的定义:

    <style name="Body">
        <item name="android:textSize">12sp</item>
        <item name="android:lineSpacingExtra">8dp</item>
        <item name="android:letterSpacing">-0.03125</item>
    </style>
Run Code Online (Sandbox Code Playgroud)

该数据类又在该对象中使用,该对象提供对版式、颜色等的访问:

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto">

    <font
        app:font="@font/some_font_regular"
        app:fontStyle="normal"
        app:fontWeight="500" />

    <font
        app:font="@font/some_font_italic"
        app:fontStyle="italic"
        app:fontWeight="500" />

    <font
        app:font="@font/some_font_bold"
        app:fontStyle="normal"
        app:fontWeight="700" />

    <font
        app:font="@font/cera_pro_bold_italic"
        app:fontStyle="italic"
        app:fontWeight="700" />

</font-family>
Run Code Online (Sandbox Code Playgroud)

最后,我们使用这个对象作为实际的 Composable:

data class AppTypography(
    private val someFontFamily: FontFamily = FontFamily(
        Font(R.font.some_font_regular, FontWeight.W500, FontStyle.Normal),
        Font(R.font.some_font_bold, FontWeight.W700, FontStyle.Normal),
        Font(R.font.some_font_italic, FontWeight.W500, FontStyle.Italic),
        Font(R.font.some_font_pro_bold_italic, FontWeight.W700, FontStyle.Italic),
    ),
    // ...
    val body: TextStyle = TextStyle(
        fontFamily = someFontFamily,
        fontWeight = FontWeight.Normal,
        fontSize = 12.sp,
        lineHeight = 24.sp
    ),
    // ...
)
internal val LocalTypography = staticCompositionLocalOf { AppTypography() }
Run Code Online (Sandbox Code Playgroud)

body然后我们在我们的其中之一中使用该样式Texts

object AppTheme {
    val colors: AppColors
        @Composable
        get() = LocalColors.current
    val typography: AppTypography
        @Composable
        get() = LocalTypography.current
    val dimensions: AppDimensions
        @Composable
        get() = LocalDimensions.current
    val shapes: AppShapes
        @Composable
        get() = LocalShapes.current
}
Run Code Online (Sandbox Code Playgroud)

比较传统 View 系统与 Compose 中的文本大小(左侧为 XML,右侧为 Compose):

在此输入图像描述

两者都使用 12sp 作为文本大小,但 Compose 看起来更小。公平地说,即使图标看起来也更小。我不确定什么会导致这种差异,也许外部可组合项的填充可能会产生影响?有人在将视图迁移到 Compose 时遇到过类似的行为吗?

aku*_*ubi 3

因此,在向 Google 提交有关此问题的问题后,我得到的建议是修改诸如letterSpacing和 之类的属性includeFontPadding(我相信在 Compose 1.2.0 中可用)。就我而言,使用Body我提到的样式,我通过以下方式接近了 XML 中字体的外观:

  • 设置letterSpacing(-0.5).sp
  • 设置fontSize16.sp
  • 设置lineHeight24.sp

我还对我们的应用程序中如何定义字体大小感到困惑 - 我们有两个dimens.xml文件,一个用于hdpixxhdpi,结果当我将字体大小从 XML 转换为 Compose 时,我使用了较小的hdpi字体大小 ( 12 sp),而我应该这样做。我用过较大的 ( 16 sp)。我还没有尝试过根据密度使用不同字体大小的解决方案,但这种方法看起来很有希望。