Android Compose使用Noto CJK Variable Font Collection时fontWeight不生效及大体积字体引发OOM的问题求助
Android Compose使用Noto CJK Variable Font Collection时fontWeight不生效及大体积字体引发OOM的问题求助
我现在遇到两个和Compose加载可变CJK字体相关的问题,想请教大家:
一、背景与第一个问题:Variable Font通过XML转Typeface后,Compose中指定fontWeight不生效
我的最终目标是从Variable Font Collection (VFC) 文件加载字体。国内多数手机支持全局自定义字体,但这类字体对Unicode CJK汉字的支持普遍不全,会导致显示不一致,所以从开发初期我就决定在App中嵌入Noto字体,希望通过VFC来减小APK体积。
因为Compose没有直接支持TTC索引的Font()方法,所以我采用了XML定义font family的方案(XML支持android:ttcIndex属性),再将其转为原生Typeface,最后转换成Compose的FontFamily使用。但测试常规可变字体时发现了问题:Text()组件并不会显示我指定的fontWeight,而是会回退到XML中定义的FontWeight.Normal(如果有的话),或者最接近的权重值。
我做的具体操作:
- 将Noto Sans CJK JP可变字体文件放到
/res/font目录 - 创建font XML配置文件(比如
sans_jp.xml),内容如下:
<font-family xmlns:android="http://schemas.android.com/apk/res/android"> <font android:font="@font/noto_sans_variable_jp" android:fontVariationSettings="'wght' 100" android:fontWeight="100"/> <!-- 省略100到900之间的其他权重配置项 --> <font android:font="@font/noto_sans_variable_jp" android:fontVariationSettings="'wght' 900" android:fontWeight="900"/> </font-family>
- 在Activity中将XML转为原生
Typeface:
val jp = resources.getFont(R.font.sans_jp)
- 在Compose的
Text组件中使用:
import androidx.compose.ui.text.font.FontFamily as ComposeFontFamily Text( text = "測試文本", fontFamily = ComposeFontFamily(jp), fontWeight = FontWeight(900) )
异常表现:
- 在Compose Preview中,文本会回退到XML中定义的最小权重100
- 在真机上运行时,文本会回退到权重400
- 补充:如果Typeface的 fallback链是相同权重的不同字体,就没有这个问题,所以我怀疑是Compose内部处理原生
Typeface的逻辑有问题?
二、第二个问题:Variable Font Collection体积过大导致OOM
后来我尝试实现了自定义的Font类和AndroidFont.TypefaceLoader来处理VFC,但又遇到了新问题:这类VFC文件体积实在太大——无衬线版本就有30+MB,衬线版本更是超过50MB,直接导致App随机出现OOM崩溃。(其实之前我也知道直接加载这么大的文件大概率会OOM,但还是想有没有办法解决这个问题,或者有没有更优的加载方案?)
想请教各位大佬,这两个问题有没有可行的解决思路?
内容来源于stack exchange
相关产品推荐
相关产品推荐

