Jetpack Compose如何从资源文件读取适配多端的字体大小?
可行解决方案
方案1:封装扩展函数屏蔽转换逻辑,兼容所有稳定版Compose
dimensionResource转SP的开销实际为轻量数值运算,且资源读取自带缓存,生产场景下几乎感知不到。你可以通过封装Composable扩展函数消除样板代码,上层无需感知底层转换逻辑:
@Composable fun @receiver:Discouraged("仅用于SP类型的dimen资源") Int.toSpFromDimenRes(): TextUnit { return with(LocalDensity.current) { dimensionResource(id = this@toSpFromDimenRes).toSp() } } // 上层调用示例 val fontSize = R.dimen.font_size_h1.toSpFromDimenRes()后续如果Compose官方推出原生的sp资源读取API,仅需修改该扩展函数内部实现即可,上层代码无需调整。
方案2:整数资源+稳定版
sp扩展,完全消除转换开销无需调用实验性的
TextUnit构造函数,Compose提供的sp扩展本身就是稳定API,你可以直接读取整数资源后调用该扩展生成TextUnit:val fontSize = integerResource(id = R.integer.font_size_h1).sp该方案没有任何多余的类型转换,全程使用稳定API,无需添加实验性注解,同时可以复用Android原生的资源限定符能力(手机、平板不同配置下定义不同的整数值)。
方案3:基于CompositionLocal的静态Typography配置
如果设计规范的字号是按设备类型明确分级的,你可以提前定义不同设备对应的字号常量集,在App初始化时判断屏幕宽度类别,通过CompositionLocal提供对应配置的Typography实例,后续直接通过
MaterialTheme.typography.h1.fontSize读取即可,完全不需要读取系统资源,性能最优:// 定义不同设备的字号配置 private val PhoneTypography = Typography( h1 = TextStyle(fontSize = 24.sp), // 其余字号配置 ) private val TabletTypography = Typography( h1 = TextStyle(fontSize = 32.sp), // 其余字号配置 ) // 主题层根据屏幕配置提供对应的Typography @Composable fun AppTheme( isTablet: Boolean = LocalConfiguration.current.smallestScreenWidthDp >= 600, content: @Composable () -> Unit ) { val typography = if (isTablet) TabletTypography else PhoneTypography MaterialTheme( typography = typography, content = content ) } // 业务层调用示例 Text(text = "标题", style = MaterialTheme.typography.h1)
内容的提问来源于stack exchange,提问作者mtotschnig
相关产品推荐
相关产品推荐

