안드로이드 앱을 개발하다 보면 종종 폰트가 맘에 안 드는 경우가 발생한다. 안드로이드 4.1.x 이후부터는 새로운 폰트가 추가되서 조금 만족스러운 결과를 보여준다. 하지만 그것도 맘에 안 드는 경우나 앱 전체에 같은 폰트를 사용해서 일관성 있는 UI를 표현하고 싶은 경우도 있다. 안드로이드 개별 컴포넌트의 폰트를 변경하는 것은 어렵지 않다. 여기서는 앱 전체 폰트를 한 번에 변경하는 방법에 대해 살펴보겠다. 아래 내용은 안드로이드 2.3 이상의 버전에서 앱 전체 폰트를 변경하는 예제이다.
1. 원하는 폰트(Roboto-Light.ttf)를 assets 폴더에 카피한다.
2. Application 클래스를 상속해서 아래(FontApplication)와 같이 구현한다.
package net.sjava.example.font_reflector;
import java.lang.reflect.Field;
import android.app.Application;
import android.content.Context;
import android.graphics.Typeface;
public class FontApplication extends Application {
@Override
public void onCreate() {
setDefaultFont(this, "DEFAULT", "Roboto-Light.ttf");
setDefaultFont(this, "SANS_SERIF", "Roboto-Light.ttf");
setDefaultFont(this, "SERIF", "Roboto-Light.ttf");
}
public static void setDefaultFont(Context ctx,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(ctx.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected static void replaceFont(String staticTypefaceFieldName,
final Typeface newTypeface) {
try {
final Field StaticField = Typeface.class
.getDeclaredField(staticTypefaceFieldName);
StaticField.setAccessible(true);
StaticField.set(null, newTypeface);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
이 과정은 Application 클래스(앱의 시작과 종료 사이클을 가지고 있는 클래스)를 사용한다. 앱이 시작할 때 리플렉션을 이용해서 폰트를 재설정하는 방식(http://stackoverflow.com/questions/2711858/is-it-possible-to-set-font-for-entire-application?rq=1) 이다.
3. AndroidManifest.xml파일에 위의 클래스 이름(FontApplication)을 등록한다.
4. values/styles.xml 파일을 아래의 형태로 수정한다.
<resources>
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<item name="android:typeface">sans</item>
</style>
<style name="AppTheme.DialogWhenLarge" parent="@android:style/Theme.Holo.Light.DialogWhenLarge">
<item name="android:typeface">sans</item>
</style>
</resources>
위 과정으로, 앱에서 표현되는 모든 문자는 FontApplication 클래스에서 등록한 폰트로 바뀌는 것을 볼 수 있다. 아래는 안드로이드 에뮬레이터 2.3버전에서 확인한 화면이다.

5. 추가 테마에서도 글꼴을 바꿔보자.
위의 4.에서 본 styles.xml 예제는 안드로이드 2.3의 예제이고 정말 간단한 예이다. 아마도 하나의 Theme만을 쓰는 쓰는 앱은 거의 없을 테니, 다른 테마에서 적용하는 방법을 살펴보자. 아래의 예제는 values-v11/styles.xml을 약간 수정한 파일이다. 위에서 안드로이드의 Theme.Holo.Light.DialogWhenLarge 테마를 AppTheme.DialogWhenLarge가 상속을 받고, 폰트만 재 정의 했다. 아래에서는 위에서 정의한 AppTheme.DialogWhenLarge를 적용한 AndroidManifest.xml의 Application 영역 부분이다.
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:name=".FontApplication"
android:theme="@style/AppTheme" >
<activity
android:name="net.sjava.example.font_reflector.IndexActivity"
android:theme="@style/AppTheme.DialogWhenLarge"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
위에서 살펴본 앱 폰트를 한 번에 변경하는 예제는 아래에서 다운받을 수 있다.
– cfile30.uf.2302334A51CA70FD162EF6.zip