文本可组合维度资源不能用作 fontSize 参数

gal*_*irl 22 android kotlin android-resources android-jetpack-compose

当我插入 fontSize =DimensionResource(id = R.dimen.textLabelTextSize) 时,其中 dimens 或 54sp 或 60sp 取决于设备,我在 Text() 上收到错误“无法使用提供的参数调用以下函数。 ” 但是当我输入像 54sp 这样的硬编码值时就很好了。奇怪的是填充修饰符维度资源(以 dp 为单位)工作正常。

       Text(
                text = textLabelItem.textLabel,
                modifier = Modifier
                    .padding(
                        start = dimensionResource(id = R.dimen.textLabelPaddingVertical),
                        top = dimensionResource(id = R.dimen.textLabelPaddingHorizontalTop),
                        end = dimensionResource(id = R.dimen.textLabelPaddingVertical),
                        bottom = dimensionResource(id = R.dimen.textLabelPaddingHorizontalBottom)
                    )
                    .background(colorResource(id = R.color.textLabelBg))
                    .border(
                        width = 2.dp,
                        color = colorResource(id = R.color.textLabelBorder),
                        shape = RoundedCornerShape(8.dp)
                    ),
                color = colorResource(id = android.R.color.background_dark),
                fontSize = dimensionResource(id = R.dimen.textLabelTextSize),
                fontWeight = FontWeight.Bold
            )
Run Code Online (Sandbox Code Playgroud)

小智 17

答案很简单,你只是忘了处理 的结果dimensionResource。您只需使用它即可value将其设置为浮动。然后你使用sp扩展就可以开始了。

我为此创建了自己的扩展:

@Composable
@ReadOnlyComposable
fun fontDimensionResource(@DimenRes id: Int) = dimensionResource(id = id).value.sp
Run Code Online (Sandbox Code Playgroud)

所以改用dimensionResource(R.dimen.your_font_size)usefontDimensionResource(R.dimen.your_font_size)

最终解决方案:

Text(text = "", fontSize = fontDimensionResource(id = R.dimen.your_font_size))
Run Code Online (Sandbox Code Playgroud)

  • 这是行不通的。当用户更改默认设备文本大小时,不会更改文本大小。 (5认同)

Ric*_*ier 11

要从 转换dpsp您需要考虑字体缩放sp- 这就是用于文本的要点。这意味着当用户更改系统字体比例时,应用程序会响应此更改。


不缩放文本

如果我们dimensionResource()在 kotlin 中请求,我们会得到一个尚未缩放的 dp 值。您可以在源代码中确认这一点,该函数被定义为返回Dp

fun dimensionResource(@DimenRes id: Int): Dp {.....}
Run Code Online (Sandbox Code Playgroud)

到 a 的基本转换value.sp 不会应用所需的缩放,因此任何依赖于此类基本计算的解决方案都将无法正常工作。

unscaledSize = dimensionResource(R.dimen.sp_size).value.sp
Run Code Online (Sandbox Code Playgroud)

(其中R.dimen.sp_size是通过调整大小声明的维度资源sp

这不能正确缩放文本大小。


更好的解决方案

为了正确地做到这一点,我们需要查看DisplayMetrics和当前scaledDensity值,定义为:

/**
* A scaling factor for fonts displayed on the display.  This is the same
* as {@link #density}, except that it may be adjusted in smaller
* increments at runtime based on a user preference for the font size.
*/
public float scaledDensity;
Run Code Online (Sandbox Code Playgroud)

此缩放值必须应用于获取的维度,以返回可用作以下内容的内容sp

val scaledSize = with(LocalContext.current.resources) {
    (getDimension(R.dimen.sp_size) / displayMetrics.scaledDensity).sp
}
Run Code Online (Sandbox Code Playgroud)

警告:这仅适用于定义为sp!的尺寸。


处理不同的尺寸类型

更好的解决方案是检查正在访问什么类型的维度资源,然后根据该类型进行计算dp,即 、sppx

这确实需要使用TypedValueTypedArray,这使得它有点复杂,但可以在MDC 主题适配器的TypedArrayUtils中找到示例代码:

internal fun TypedArray.getTextUnitOrNull(
    index: Int,
    density: Density
): TextUnit? {
    val tv = tempTypedValue.getOrSet { TypedValue() }
    if (getValue(index, tv) && tv.type == TypedValue.TYPE_DIMENSION) {
        return when (tv.complexUnitCompat) {
            // For SP values, we convert the value directly to an TextUnit.Sp
            TypedValue.COMPLEX_UNIT_SP -> TypedValue.complexToFloat(tv.data).sp
            // For DIP values, we convert the value to an TextUnit.Em (roughly equivalent)
            TypedValue.COMPLEX_UNIT_DIP -> TypedValue.complexToFloat(tv.data).em
            // For another other types, we let the TypedArray flatten to a px value, and
            // we convert it to an Sp based on the current density
            else -> with(density) { getDimension(index, 0f).toSp() }
        }
    }
    return null
}
Run Code Online (Sandbox Code Playgroud)

最佳解决方案

理想情况下,我们在使用 Compose 时不应提取资源并进行转换。我们应该改用主题常量。

我们可能都在这个页面上,因为我们有一些 XML 布局和 Compose 中的其他布局。我们可能正在经历转换过程。

处理此类转换的最佳方法是使用 Material Components MDC-Android Compose Theme Adapter来处理所有这些情况。

它的作用不仅仅是文本大小计算,也是我们迁移到 Compose 过程中应该达到的目标。


Gab*_*tti 3

发生这种情况是因为该函数dimensionResource返回一个Dp值并fontSize使用Sp值。

目前您无法使用它。