Typeface — 개요, 글꼴 종류 및 Android에서의 작업

저자: IT Sectr 게시일: 2026-07-23 읽는 시간: 9 분

Typeface — android.graphics 패키지의 Android SDK 클래스로, 글꼴의 디자인을 나타내고 TextView 및 다른 UI 컴포넌트에서 텍스트 커스터마이징에 사용됩니다. Typeface는 글꼴 패미리, 그 가우르기(normal, bold) 및 스타일(normal, italic)을 정의합니다. Google Developers에 따르면, Typeface는 TTF, OTF 파일, XML 글꼴 및 시스템 리소스에서의 로드를 지원합니다. 이것은 Android 애플리케이션에서 타이포그래피 관리를 위한 중심 클래스입니다.

중요 포인트

  • Typeface — 패미리와 스타일을 가진 글꼴 디자인을 나타내는 Android 클래스
  • 내장 스타일: Typeface.NORMAL, BOLD, ITALIC, BOLD_ITALIC
  • 글꼴이 로드되는 곳 XML 리소스, TTF/OTF 파일, assets 또는 시스템 폴더
  • Android 8.0+ res/font의 XML 리소스를 통한 글꼴 로드 지원
  • Typeface.create() 지정된 패미리와 스타일로 인스턴스 생성

Typeface란?

Typeface — 글꼴 정보를 캡슐화하는 Android 클래스입니다: 그 패미리(Roboto, Arial, Serif) 및 스타일 수정자(bold, italic)입니다. iOS의 UIFont와 달리, Typeface에는 크기 정보가 포함되지 않습니다 — 텍스트 크기는 TextView의 textSize 특성 또는 Spannable의 TextStyle을 통해 별도로 설정됩니다. Typeface는 글꼴의 디자인과 패미리에 대해서만 당당합니다.

이 클래스는 모든 API 레벨에서 사용 가능합니다. Android 4.4 이전에는 Typeface가 제한된 시스템 글꼴만 지원했습니다: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF. Android 8.0(API 26)부터는 XML 리소스를 통한 커스털 글꼴 로드 지원이 추가되었고, Android 10에서는 가변 글꼴 지원이 추가되었습니다.

내장 Typeface 상수

Android는 여러 개의 내장 Typeface 인스턴스를 제공합니다: Typeface.DEFAULT — 시스템 글꼴 Roboto(Material) 또는 Noto(AOSP), DEFAULT_BOLD — 굵은 표현, MONOSPACE — 코드용 고정폭 글꼴, SERIF — 세리프 글꼴(Noto Serif), SANS_SERIF — 산스리프(Noto Sans). 이 상수들은 컨텍스트 없이 사용 가능하고 파일 읽기 권한이 필요하지 않습니다.

시스템에서 Typeface

Android 시스템은 시스템 UI, 제목, 캡션 및 알림을 포함한 모든 텍스트를 렌더링하는 데 Typeface를 사용합니다. 각 애플리케이션은 테마(android:fontFamily) 또는 프로그래머티켁으로 setTypeface()를 통해 기본 글꼴을 재정의할 수 있습니다. Typeface는 TextView에서 상속된 모든 컴포넌트(버튼, EditText 및 커스털 뷰)에 적용됩니다.

리소스에서 Typeface 생성

Android 8.0+에서는 res/font에 글꼴을 추가하고 XML 리소스를 통해 사용할 수 있습니다. 글꼴 파일(TTF 또는 OTF)을 res/font에 보관하면 R.font.font_name 참조가 생성됩니다. Typeface는 ResourcesCompat.getFont(context, R.font.font_name)을 통해 로드됩니다. 이 방법이 좋은 이유는 글꼴이 APK에 컴파일되고 ProGuard 빌드 시스템을 지원하기 때문입니다.

리소스 접근 방식은 res/font의 XML 파일을 통한 글꼴 패미리도 지원합니다: 서로 다른 디자인(regular, bold, italic)에 대해 여러 파일을 지정할 수 있고, setTypeface를 호출할 때 시스템이 자동으로 적합한 파일을 선택합니다. 이를 통해 타이포그래피가 단순화됩니다 — 테마에서 fontFamily를 설정하면 Android가 자동으로 올바른 파일을 선택합니다.

Typeface.create 사용

Typeface.create(Typeface family, int style) 메소드는 지정된 패미리와 스타일로 글꼴 인스턴스를 생성합니다. 패미리에 이미 요청된 스타일이 있는 경우 기존 인스턴스가 반환됩니다. 스타일이 없는 경우 Android는 그것을 합성합니다 — 기본 글꼴에 위장 굵은 표현 또는 인공 이탤릭을 적용합니다.

kotlin
val boldTypeface = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD)
val italicTypeface = Typeface.create(Typeface.MONOSPACE, Typeface.ITALIC)
val customTypeface = ResourcesCompat.getFont(context, R.font.montserrat_regular)
textView.typeface = boldTypeface

합성된 위장 굵은 표현은 안질술과에서 질이 나쁜 수 있습니다. 최고의 결과를 위해서는 실제 bold 디자인이 있는 글꼴 파일을 사용하세요. Typeface.create()는 존재하지 않는 스타일로 예외를 발생시키지 않고 가장 근접한 사용 가능한 변체를 반환합니다.

파일과 Assets에서 Typeface

assets에서 Typeface를 로드하려면 Typeface.createFromAsset(assetManager, path)를 사용하세요. 글꼴은 src/main/assets/fonts/ 디렉토리에 보관되고 경로는 assets 상대적으로 지정됩니다. 이 방법은 모든 Android 버전에서 작동하지만 글꼴 패미리를 지원하지 않으며 각 디자인에 대해 특정 파일을 지정해야 합니다.

Typeface.createFromFile(File) 메소드는 파일 시스템에서 임의의 파일로부터 글꼴을 로드합니다. 이것은 네트워크에서 다운로드하거나 애플리케이션의 내부 저장소에 복사된 글꼴에 유용합니다. createFromFile는 컨텍스트가 필요하지 않으므로 백그라운드 작업에 편리하지만 파일이 읽기 가능해야 합니다.

캐시를 통한 Assets 로드

createFromAsset을 통해 Typeface를 반복적으로 로드하면 중복 객체가 생성될 수 있습니다. createFromAsset을 호출할 때마다 파일이 다시 로드됩니다. HashMap을 사용하여 Typeface 캐시를 구현할 것을 권장합니다. 여기서 파일 경로가 키가 되고 로드된 인스턴스가 값이 됩니다. 이것은 서로 다른 글꼴 종류가 있는 리스트에서 특히 중요합니다.

kotlin
object TypefaceCache {
    private val cache = mutableMapOf<String, Typeface>()
    fun getTypeface(context: Context, filename: String): Typeface {
        return cache.getOrPut(filename) {
            Typeface.createFromAsset(context.assets, "fonts/$filename")
        }
    }
}
// Usage
val typeface = TypefaceCache.getTypeface(context, "Roboto-Bold.ttf")

메모리 캐시는 글꼴이 애플리케이션 세션당 단 한 번만 로드되도록 보장합니다. 구성 변경(화면 회전)시에도 companion 객체에 있으므로 캐시가 유지됩니다. 메모리부족 시 캐시를 지우려면 WeakHashMap을 사용하거나 onTrimMemory를 청청b하세요.

TextView에 Typeface 적용

Typeface는 setTypeface(Typeface tf) 또는 setTypeface(Typeface tf, int style) 메소드를 통해 TextView에 적용됩니다. 둘째 변체는 현재 글꼴에 대한 스타일(bold/italic)을 변경할 수 있습니다. XML에서는 android:fontFamily 속성을 글꼴 또는 시스템 패미리에 대한 참조와 함께 사용합니다. 프로그래머티켁 설정에서는 setTypeface(monospaceTypeface)를 호출하면 지정된 글꼴로 대체됩니다.

Typeface는 전체 TextView 텍스트에 영향을 미칩니다. 한 줄에 다른 글꼴이 필요한 경우 TypefaceSpan이 있는 SpannableString을 사용하세요. TypefaceSpan은 Typeface 또는 패미리를 수락하고 문자 범위에 적용됩니다. 이것은 중첩된 컴포넌트 없이 하나의 TextView 내에서 글꼴을 혼합하는 유일한 방법입니다.

부분 텍스트에 대한 TypefaceSpan

TypefaceSpan을 문자열의 일부에만 적용하세요. 예를 들어, 텍스트의 변수 값은 고정폭으로 하고 나머지 텍스트는 시스템 글꼴로 남겨야 할 경우가 있습니다. SpannableString을 생성하고 원하는 범위에 MONOSPACE Typeface를 가진 TypefaceSpan을 설정하세요. 나머지 텍스트는 원래 TextView 글꼴을 유지합니다.

kotlin
val text = "Code: variableName"
val spannable = SpannableString(text)
spannable.setSpan(
    TypefaceSpan(Typeface.MONOSPACE),
    5, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
spannable.setSpan(
    ForegroundColorSpan(Color.BLUE),
    5, text.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannable

텍스트 “variableName”는 파란색 고정폭 글꼴로 표시되고, “Code:”라는 단어는 시스템 글꼴로 남아있습니다. TypefaceSpan은 텍스트 각 세그먼트를 정확하게 제어하기 위해 다른 스패과 결합할 수 있습니다.

Typeface를 통한 커스털 글꼴

Android는 여러 글꼴 포맷을 지원합니다: TrueType (TTF), OpenType (OTF) 및 Android 10부터 Web Open Font Format (WOFF2). TTF와 OTF는 커스털 글꼴에 대한 주요 포맷입니다. XML 글꼴(Font Family)은 별도의 포맷이 아니라 각 디자인에 사용할 파일을 설명하는 기능을 합니다.

res/font를 통해 커스털 글꼴을 사용하려면 regular, bold 및 italic에 대한 글꼴 파일 경로를 지정하는 패미리 XML 파일을 생성하세요. 그런 다음 애플리케이션 테마에서 android:fontFamily="@font/custom_family"를 지정하세요. 이 테마를 사용하는 모든 TextView 인스턴스는 각 스타일에 대해 자동으로 올바른 디자인을 획득합니다.

다운로드된 글꼴 로드

네트워크에서 글꼴을 다운로드한 경우 filesDir 또는 cacheDir에 저장하고 Typeface.createFromFile을 통해 로드하세요. 로드 후에는 TextView의 Typeface를 업데이트하세요. 비동기 로드를 위해서는 coroutine 또는 DownloadManager를 사용하고, 완료 후 Handler를 통해 UI 스레드에 포스트하세요. 이것은 주문에 따라 로드되는 커스털 타이포그래피를 가진 애플리케이션의 일반적인 시나리오입니다.

kotlin
// Save font file to internal storage
val fontFile = File(context.cacheDir, "downloaded-font.otf")
fontFile.outputStream().use { output ->
    // inputStream from network
    inputStream.copyTo(output)
}
// Create Typeface from file
val downloadedTypeface = Typeface.createFromFile(fontFile)
textView.typeface = downloadedTypeface

로드 전에 파일 사용 가능성을 확인하세요: 파일이 구처되거나 유효하지 않은 경우 Typeface.createFromFile이 RuntimeException을 발생시킵니다. 호출을 try-catch로 감싸고 오류 시 기본 시스템 글꼴으로 돌아가는 것을 권장합니다.

Jetpack Compose에서 Typeface

Jetpack Compose에서는 Android SDK의 Typeface가 직접 사용되지 않습니다. 대신 Compose는 타이포그래피를 위해 FontFamilyFontWeight를 제공합니다. FontFamily는 Font.Resource와 Font.File을 통해 로드됩니다. Compose의 타이포그래피 시스템은 MaterialTheme.typography를 통해 정의되며, 각 스타일(h1, body1, button)에 커스털 FontFamily를 할당할 수 있습니다.

리소스에서 글꼴을 로드하려면 Compose는 Font(R.font.font_name, weight, style)을 사용합니다. assets에서 글꼴은 Font(assetPath = "fonts/custom.otf", weight, style)를 통해 로드됩니다. 글꼴을 정의한 후 Typography에 전달되고, 그 다음 MaterialTheme.typography.bodyLarge 및 유사한 스타일을 통해 적용됩니다.

Typeface를 Compose 글꼴로 변환

Android SDK를 통해 생성된 기존 Typeface가 있는 경우 TypefaceAdapter를 통해 Compose에서 사용하거나 Typeface를 기반으로 FontFamily를 생성할 수 있습니다. Typeface.create에서 Typeface를 가져와 FontFamily.Custom(listOf(Font(typeface)))에 전달하세요. 그러나 Font.Resource를 사용한 네이티브 접근 방식이 Compose에 더 잘 최적화되어 있으므로 권장됩니다.

성능과 캐시

파일에서 글꼴을 로드하는 것은 가능한 비용이 많이 드는 작업입니다. Typeface.createFromAsset 또는 Typeface.createFromFile을 호출할 때마다 디스크에서 파일을 읽고, 분석하고, Typeface 객체를 생성합니다. 1-2MB 글꼴의 경우 콜드 시작에 10-50ms가 걸립니다. 커스털 글꼴이 있는 애플리케이션에서 Typeface 캐시는 필수적인 실천입니다.

Android SDK는 createFromAsset 또는 createFromFile를 통해 생성된 글꼴을 캐시하지 않습니다. Zygote 프로세스에서 미리 로드되는 시스템 글꼴과 달리, 커스털 글꼴은 액세스할 때마다 로드됩니다. 글꼴 식별자를 키로 한 LruCache 또는 ConcurrentHashMap을 사용할 것을 권장합니다. 10-20 인스턴스의 캐시 크기는 일반적인 애플리케이션 글꼴 세트를 다 루는데 적합합니다.

Font Family를 통한 최적화 (API 26+)

Android 8.0+ XML Font Family를 통해 글꼴 로드를 최적화합니다. XML 레이아웃에서 android:fontFamily="@font/my_family"를 지정하면 Android는 글꼴을 지연 로드합니다 — 컴포넌트가 보이는 경우에만 로드합니다. 또한 시스템은 ResourcesCompat.getFont()를 통해 로드된 글꼴을 글로벌 프로세스 캐시에 저장합니다. 이로써 리소스 접근 방식이 가장 성능이 좋습니다.

RecyclerView에서 Typeface

RecyclerView 어댕터에서 Typeface를 사용할 때 onBindViewHolder 메소드에서 글꼴을 로드하지 않는 것이 중요합니다. 어댕터를 생성할 때 한 번 로드하거나 미리 로드된 Typeface를 가진 ViewHolder를 사용하세요. 리스트의 각 항목에 고유한 글꼴이 필요한 경우 WeakHashMap을 사용하여 캐시를 구현하고, 메모리를 절약하기 위해 보이는 위치 밖으로 스크롤할 때 캐시를 지우세요.

자주 묻는 질문

Android에서 Typeface와 FontFamily의 차이점은 무엇인가요?

Typeface — 프로그래머티켁 사용을 위한 구체적인 글꼴 인스턴스입니다. FontFamily — 서로 다른 디자인(regular, bold, italic)에 대한 글꼴 파일 그룹을 설명하는 XML 리소스입니다. 실행 시에 FontFamily는 ResourcesCompat.getFont를 통해 Typeface로 변환됩니다. Typeface는 FontFamily를 거치지 않고 파일에서 직접 생성할 수 있습니다.

컨텍스트 없이 Typeface를 로드하려면?

Typeface.createFromFile(File) 또는 Typeface.DEFAULT를 사용하세요. 이 메소드들은 파일 시스템 또는 내장 상수로 작동하므로 컨텍스트가 필요하지 않습니다. assets 또는 리소스에서 로드하려면 AssetManager와 애플리케이션 리소스에 접근해야 하므로 컨텍스트가 필요합니다.

Typeface를 WebView에서 사용할 수 있나요?

아니요, WebView는 글꼴을 지정하기 위해 CSS font-family 속성을 사용합니다. WebView에서 커스털 글꼴을 사용하려면 글꼴 파일을 assets에 둑니다가 CSS에서 @font-face를 통해 지정하세요. Typeface Android SDK는 네이티브 UI 컴포넌트(TextView 및 그 후속)에서만 작동합니다.

Typeface는 가변 글꼴을 지원하나요?

네, Android 10(API 29)부터 지원합니다. 가변 글꼴은 ResourcesCompat.getFont 또는 Typeface.createFromFile을 통해 로드됩니다. 변이 축(weight, width)을 구성하려면 Compose에서 FontStyle 또는 XML 속성을 사용하세요. 프로그래머티켁 축 변경은 Skia의 저수준 API를 통해서만 가능합니다.

일부 글꼴에서 setTypeface가 작동하지 않는 이유는?

가장 일반적인 원인: 프로젝트에 글꼴 파일이 없거나, 파일 이름이 잘못되었거나, 글꼴이 구처되거나, 파일에 없는 합성된 스타일이 사용되고 있기 때문입니다. 파일이 res/font 또는 assets에 추가되었고, 리소스 접근 방식의 경우 이름이 확장자 없이 지정되었는지 확인하세요.

요약

  • Typeface — 패미리와 디자인 스타일을 가진 글꼴을 표현하는 Android 클래스
  • 내장 상수: DEFAULT, DEFAULT_BOLD, MONOSPACE, SERIF, SANS_SERIF
  • 로드 ResourcesCompat.getFont, Typeface.createFromAsset, createFromFile 통해
  • XML Font Family (API 26+) — 커스털 글꼴 선호 방법
  • TypefaceSpan SpannableString을 통해 텍스트 일부에 글꼴 적용 가능
  • Typeface 캐시 는 필수 — HashMap 또는 LruCache 사용
  • Compose에서 Android SDK Typeface 대신 FontFamily와 FontWeight 사용

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기