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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:23:25