You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose像素级复刻PS布局遇问题:字体与边距偏差求助

问题描述

我的目标

拿到一份简单的Photoshop文件,希望完全复刻其中的像素级效果。目标设备永远不会改变显示分辨率或其他参数。

Photoshop设计图

各项像素参数清晰明确:

  • 宽度 = 111
  • 高度 = 66
  • 分隔线后内边距 = 15
  • "PM"后内边距 = 15
  • "TIME"与"PM"之间内边距 = 8
  • "TIME"字号像素值 = 24
  • "PM"字号像素值 = 15

我的代码:

Row(
    modifier = Modifier
        .width(PixelToDp(111))
        .height(PixelToDp(66))
        .fillMaxSize()
        .background(colorResource(R.color.black)),
    horizontalArrangement = Arrangement.Start,
    verticalAlignment = Alignment.CenterVertically
) {

    Image(
        painter = painterResource(id = R.drawable.statusbar_splitline),
        contentDescription = null,
        modifier = Modifier.padding(end = PixelToDp(pixelSize = 15))
    )

    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        BentleyText(
            text = "12:34",
            pixelSize = 24,
            modifier = Modifier.padding(end = PixelToDp(pixelSize = 8))
        )
        BentleyText(
            text = "PM", pixelSize = 15,
            modifier = Modifier
                .padding(end = PixelToDp(pixelSize = 15))
                .width(IntrinsicSize.Min) // 尝试的调整
        )

    }
}

文本相关的像素转SP实现

@Composable
fun BentleyText(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = colorResource(id = R.color.white),
    pixelSize: Int = 14

) {
    val pixelSizeInSp = with(LocalDensity.current) { pixelSize.toSp() }
    Text(
    text,
        modifier = modifier,
        fontFamily = Font(R.font.bentleyw1g_smcon_light_mib3).toFontFamily(),
        fontStyle = Font(R.font.bentleyw1g_smcon_light_mib3).style,
        fontWeight = Font(R.font.bentleyw1g_smcon_light_mib3).weight,

        color = color,
        fontSize = pixelSizeInSp
    )
}

其他元素的像素转DP实现

@Composable
fun PixelToDp(pixelSize: Int): Dp {
    return with(LocalDensity.current) { pixelSize.toDp() }
}

遇到的问题

使用上述精确像素值后,效果完全不符:字体大小和Photoshop不一致,内边距间距偏差大,仅宽高显示正确。

当前实现效果

预览参考线:
预览参考线

解决方案

1. 修复字体大小偏差

Photoshop的字号是固定像素值,直接转SP会受系统字体缩放影响,导致尺寸偏差。修改BentleyText,强制按1:1像素映射,关闭字体缩放适配:

@Composable
fun BentleyText(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = colorResource(id = R.color.white),
    pixelSize: Int = 14
) {
    // 固定像素转TextUnit,不受系统缩放影响
    val fontSize = with(LocalDensity.current) {
        pixelSize.toDp().value.sp
    }
    Text(
        text = text,
        modifier = modifier,
        fontFamily = FontFamily(Font(R.font.bentleyw1g_smcon_light_mib3)),
        color = color,
        fontSize = fontSize,
        // 强制关闭字体缩放
        textScaleX = 1f,
        textScaleY = 1f,
        // 若Photoshop有指定行高,需添加对应像素转的sp值
        lineHeight = fontSize
    )
}

同时确认字体文件和Photoshop完全一致,避免字距、行高默认值差异。

2. 修正内边距与布局偏差

  • 外层Row的.fillMaxSize()会突破设置的宽高限制,直接移除:
Row(
    modifier = Modifier
        .width(PixelToDp(111))
        .height(PixelToDp(66))
        .background(colorResource(R.color.black)),
    horizontalArrangement = Arrangement.Start,
    verticalAlignment = Alignment.CenterVertically
) {
    // 内部元素
}
  • 强制1:1像素转DP,忽略设备密度差异:
@Composable
fun PixelToDp(pixelSize: Int): Dp {
    return Density(density = 1f).run { pixelSize.toDp() }
}
  • 分隔线图片添加contentScale = ContentScale.None,避免自动缩放:
Image(
    painter = painterResource(id = R.drawable.statusbar_splitline),
    contentDescription = null,
    modifier = Modifier.padding(end = PixelToDp(15)),
    contentScale = ContentScale.None
)

3. 额外调试建议

开启Compose预览的「Show Pixel Grid」,逐像素对比元素位置与Photoshop参考线,确认每个控件的尺寸、间距是否完全匹配。

内容的提问来源于stack exchange,提问作者Vaio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:40:25