如何在Kotlin开发的Android应用中编程获取并使用系统字体?
在Kotlin中获取并应用设备系统字体到Android UI
一、获取设备已安装的系统字体列表
Android不同版本提供了不同的API来获取系统字体,以下是兼容API 21+的实现:
import android.content.Context import android.os.Build import android.graphics.fonts.FontManager import java.io.File fun getSystemFonts(context: Context): List<String> { val fontNames = mutableListOf<String>() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // API 29+ 使用官方FontManager API获取系统字体 val fontManager = context.getSystemService(Context.FONT_MANAGER_SERVICE) as FontManager val fontFamilies = fontManager.getInstalledFontFamilies() fontFamilies.forEach { family -> family.name?.takeIf { it.isNotBlank() }?.let { fontNames.add(it) } } } else { // 低版本扫描系统默认字体目录(适配多数ROM) val systemFontDir = File("/system/fonts/") if (systemFontDir.exists() && systemFontDir.isDirectory) { systemFontDir.listFiles()?.forEach { file -> val fileName = file.name if ((fileName.endsWith(".ttf") || fileName.endsWith(".otf")) && !fileName.startsWith(".")) { fontNames.add(fileName.substringBeforeLast(".")) } } } } return fontNames.distinct() }
二、将系统字体应用到文本元素
获取字体名称后,可直接将其应用到TextView、Button等文本组件,以下是封装好的应用方法:
import android.content.Context import android.os.Build import android.graphics.Typeface import android.graphics.fonts.FontManager import android.graphics.fonts.FontFamilyRequest import android.widget.TextView import java.io.File fun applySystemFont(textView: TextView, fontName: String) { val typeface = when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> { // API 29+ 用FontManager获取可靠的Typeface实例 val fontManager = textView.context.getSystemService(Context.FONT_MANAGER_SERVICE) as FontManager try { fontManager.getTypeface( FontFamilyRequest.Builder( listOf(FontFamilyRequest.FontFamilyLocator(fontName)) ).build(), Context.RESTRICT_TO_SYSTEM_FONTS ) ?: Typeface.DEFAULT } catch (e: Exception) { Typeface.DEFAULT } } else -> { // 低版本从系统字体文件创建Typeface,处理异常避免崩溃 runCatching { Typeface.createFromFile(File("/system/fonts/${fontName}.ttf")) }.getOrElse { runCatching { Typeface.createFromFile(File("/system/fonts/${fontName}.otf")) }.getOrDefault(Typeface.DEFAULT) } } } textView.typeface = typeface }
三、使用示例
在Activity中调用上述方法,将系统字体应用到UI组件:
import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import android.widget.TextView class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val sampleTextView = findViewById<TextView>(R.id.sample_text_view) val systemFonts = getSystemFonts(this) // 示例:应用第一个可用的系统字体 systemFonts.firstOrNull()?.let { fontName -> applySystemFont(sampleTextView, fontName) } } }
注意事项
- API兼容性:API 29+的
FontManager是官方推荐方案,不受定制ROM的字体目录变化影响;低版本依赖系统目录扫描,部分定制ROM可能字体路径不同,需额外适配。 - 异常处理:应用字体时必须捕获异常,避免因字体文件不存在或权限问题导致崩溃。
- 字体名称:部分系统字体名称可能包含特殊字符,使用时需确保名称与实际文件匹配。
内容的提问来源于stack exchange,提问作者Viraj S
相关产品推荐
相关产品推荐

