안드로이드 앱을 개발하다 보면 종종 폰트가 맘에 안 드는 경우가 발생한다. 안드로이드 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