如何在Jetpack Compose中为各Locale设置专属字体系列
Compose 的排版体系完全独立于原生 View 系统的 style.xml 配置,因此原有基于多语言 values 文件夹修改 style 的方案无法直接生效,你可以通过以下两种方案实现多地区对应不同字体系列的需求:
方案1:通过资源限定符映射字体(兼容原有适配逻辑)
该方案沿用你之前熟悉的多语言资源目录适配思路,无需硬编码语言判断逻辑:
- 首先在默认
res/values/目录下创建fonts.xml,定义字体别名指向默认字体:
<resources> <item name="locale_specific_font" type="font">@font/myfont_default</item> </resources>
- 对应每个需要适配的语言,在对应语言的 values 目录(比如
values-zh、values-ja)下创建同名fonts.xml,修改别名指向对应语言的字体文件:
示例(中文适配的values-zh/fonts.xml):
<resources> <item name="locale_specific_font" type="font">@font/myfont_chinese</item> </resources>
- 在 Compose 中动态读取资源对应的字体,构建本地化的 Typography:
@Composable fun rememberLocalizedTypography(): Typography { val context = LocalContext.current // 读取当前Locale对应的字体资源 val fontResId = remember { context.resources.getIdentifier("locale_specific_font", "font", context.packageName) } val fontFamily = remember(fontResId) { FontFamily( Font(fontResId, FontWeight.Normal) // 按需添加其他字重的Font配置 ) } return remember(fontFamily) { Typography( body1 = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.Normal, fontSize = 16.sp ), button = TextStyle( fontFamily = fontFamily, fontWeight = FontWeight.SemiBold, fontSize = 14.sp ), defaultFontFamily = fontFamily ) } }
- 在你的自定义主题 Composable 中调用上述方法,将返回的 Typography 传入
MaterialTheme即可,系统切换语言时会自动重组加载对应字体。
方案2:代码判断Locale动态切换字体
如果不需要兼容原有适配逻辑,不想维护多份xml资源,可以直接在代码中判断当前Locale返回对应字体:
@Composable fun getLocalizedFontFamily(): FontFamily { val currentLocale = LocalConfiguration.current.locales[0] return when(currentLocale.language) { "zh" -> FontFamily(R.font.myfont_chinese) "ja" -> FontFamily(R.font.myfont_japanese) "ko" -> FontFamily(R.font.myfont_korean) else -> FontFamily(R.font.myfont_default) } }
将返回的 FontFamily 注入到你的 Typography 配置中传入主题即可。
注意事项
- 所有自定义字体文件需要提前放到
res/font/目录下,命名符合Android资源命名规范(仅小写字母、数字和下划线) - 如果支持App内手动切换语言,切换后需要更新Context的Configuration配置,触发Compose重组即可自动加载对应字体
内容的提问来源于stack exchange,提问作者Mohammad Derakhshan
相关产品推荐
相关产品推荐

