Android O에서 Downloadable Font가 소개되었습니다. Downloadable Font는 App이 Font Provider를 통해서 Font를 다운받아 사용할 수 있는 기능입니다. 이 기능을 사용하면 App size가 줄어드는 장점과 기본 Font는 Googe Play Service가 제공하기 때문에 Font 관리가 편하다는 장점이 있습니다.
이전에는 Font를 변경하려면 /Asset
에 Font 파일을 넣어야 해서 App size가 Font size만큼 더 커질 수 밖에 없었는데요. 이제는 다운받아 사용할 수 있습니다.
물론 Google Play Service가 제공하는 기본 Font 외에 특정 Font를 사용하고 싶다면 App에 포함시켜야하고, 다른 App과 공유를 하고 싶으면 Provider를 구현해야 합니다.
Downloadable Font는 Android Support Library 26에서 Downloadable Font를 지원하며, Android 4.0(API 14) 이상의 모든 디바이스에서 동작하도록 지원합니다.
아래 그림은 Downloadable Font의 구조를 간단히 보여줍니다.
Google Play Service를 통해 Font 변경
Google Play Service가 기본적으로 Font를 제공합니다. 여기서 제공해주는 Font를 사용한다면 직접 Font를 App에 포함시킬 필요가 없습니다. 물론 Activity가 loading될 때 Provider를 통해서 받기 때문에 직접 App에서 Font를 loading하는 것보다 느릴 수 있습니다. 하지만 Android는 App process가 생성될 때 미리 loading할 수 있도록 하여 이 문제를 해결하려고 하였습니다.
Google Play Service에서 어떤 Font를 제공하는지, Provider는 어떻게 접근하는지 알기 어려울 수 있는데요, Android Studio 3.0은 간단한 UX로 이를 쉽게 사용하도록 도와줍니다.
Android Studio 3.0을 통해 다운로더블 폰트를 사용하는 방법을 알아보겠습니다.
프로젝트 생성하기
[File] >> [New] >> [New Project]
에서 Empty Activity를 선택하시고 새 프로젝트를 생성해주세요. (Compile SDK는 API 26입니다.)
프로젝트를 생성하면 자동적으로 MainActivity.java와 activity_main.xml 파일이 생성됩니다.
/app/build.gradle
에 support-compat
version 26이상이 포함되어야합니다. (명시적으로 설정안해도 포함되어있는 것 같네요?)
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:support-compat:26.1.0'
}
Android Studio에서 Font 설정
Design view에서 activity_main.xml
의 TextView를 선택하면 Attributes 창이 보입니다. fontFamily
의 메뉴를 눌러 More Fonts
를 누르면 설정화면이 보입니다.
왼쪽에는 Google Play Service에서 지원하는 Font들이 보입니다. 오른쪽 옵션 중에 Create Downloadable Font
는 Downloadable font를 이용하겠다는 것이고,
Add font to project
는 Downlodable font를 이용하지 않고 App에 Font 파일을 추가하여 직접 loading하겠다는 의미입니다.
원하는 Font와 Create Downloadable Font
를 선택하고 OK버튼을 누르세요.
OK버튼을 누르면 다음 3개의 파일이 생성됩니다.(저는 Aladin Font 선택)
- /res/font/aladin.xml
- /res/values/font_certs.xml
- /res/values/preloaded_fonts.xml
aladin.xml
은 Provider에서 Font를 가져오는 Font-Family에 대한 정보입니다.
font_certs.xml
은 Provider에 접근하는데 필요한 certification에 대한 정보입니다.
위의 두 파일에 대한 정보는 꼭 정의되어야 하지만, preloaded_fonts.xml
은 꼭 필요하지 않습니다. Activity가 실행될 때 Font를 loading하면 delay가 발생할 수 있는데요. preloaded_fonts.xml
에 App process가 실행될 때 미리 loading할 Font를 정의하여 delay를 줄일 수 있습니다.
XML에서 Font 설정
Font는 XML, JAVA에서 모두 설정할 수 있는데요. XML이 매우 간단합니다. View의 fontFamily
속성에 /res/font/
에 정의한 font 명을 입력하면 됩니다.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/aladin"
android:text="Hello World!"/>
Java에서 Font 설정
Java에서 code로 설정하는 방법에 대해서 알아보겠습니다.
FontRequest 객체에 Provider의 Authority, Package, Query, Certs에 대한 Params을 입력합니다. 그리고 FontsContractCompat로 requestFont()를 호출하여 down을 받고 Font를 변경할 TextView에 직접 set하면 됩니다.
주의할 점은 App의 Handler에서 Download를 하기 때문에 Main thread를 Handler로 넘겨주면 UI 작업에 문제가 될 수 있습니다. 그래서 별도로 Thread를 생성하고 그 Looper로 Handler를 생성하는 것이 좋을 것 같습니다.
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";
private Handler mHandler;
private TextView mTextView;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.tv_hello);
FontRequest request = new FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
"Aladin",
R.array.com_google_android_gms_fonts_certs);
FontsContractCompat.FontRequestCallback callback =
new FontsContractCompat.FontRequestCallback() {
@Override
public void onTypefaceRetrieved(Typeface typeface) {
// Download succeeded
mTextView.setTypeface(typeface);
}
@Override
public void onTypefaceRequestFailed(int reason) {
// Download failed
}
};
FontsContractCompat.requestFont(this, request, callback,
getHandlerThreadHandler());
}
private Handler getHandlerThreadHandler() {
if (mHandler == null) {
HandlerThread handlerThread = new HandlerThread("fonts");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
}
return mHandler;
}
}
Preload 설정
preload 설정은 AndroidManifest.xml
의 Application TAG 안에 아래처럼 meta-data
로 설정을 할 수 있습니다.
<application
......>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
결과
실행해보면 Font가 변경된 것을 확인할 수 있습니다.
참고
- 예제로 사용한 코드는 GitHub: Downloadable Font에서 확인하실 수 있습니다.
- Downloadable Font: Android API Guide
Related Posts
- Android 14 - 사진/동영상 파일, 일부 접근 권한 소개
- Android - adb push, pull로 파일 복사, 다운로드
- Android 14 - 암시적 인텐트 변경사항 및 문제 해결
- Jetpack Compose - Row와 Column
- Android 13, AOSP 오픈소스 다운로드 및 빌드
- Android 13 - 세분화된 미디어 파일 권한
- Android 13에서 Notification 권한 요청, 알림 띄우기
- Android 13에서 'Access blocked: ComponentInfo' 에러 해결
- 에러 해결: android gradle plugin requires java 11 to run. you are currently using java 1.8.
- 안드로이드 - 코루틴과 Retrofit으로 비동기 통신 예제
- 안드로이드 - 코루틴으로 URL 이미지 불러오기
- Android - 진동, Vibrator, VibrationEffect 예제
- Some problems were found with the configuration of task 에러 수정
- Query method parameters should either be a type that can be converted into a database column or a List
- 우분투에서 Android 12 오픈소스 다운로드 및 빌드
- Android - ViewModel을 생성하는 방법
- Android - Transformations.map(), switchMap() 차이점
- Android - Transformations.distinctUntilChanged() 소개
- Android - TabLayout 구현 방법 (+ ViewPager2)
- Android - 휴대폰 전화번호 가져오는 방법
- Android 12 - Splash Screens 알아보기
- Android 12 - Incremental Install (Play as you Download) 소개
- Android - adb 명령어로 bugreport 로그 파일 추출
- Android - adb 명령어로 App 데이터 삭제
- Android - adb 명령어로 앱 비활성화, 활성화
- Android - adb 명령어로 특정 패키지의 PID 찾기
- Android - adb 명령어로 퍼미션 Grant 또는 Revoke
- Android - adb 명령어로 apk 설치, 삭제
- Android - adb 명령어로 특정 패키지의 프로세스 종료
- Android - adb 명령어로 screen capture 저장
- Android - adb 명령어로 System 앱 삭제, 설치
- Android - adb 명령어로 settings value 확인, 변경
- Android 12 - IntentFilter의 exported 명시적 선언
- Android - adb 명령어로 공장초기화(Factory reset)
- Android - adb logcat 명령어로 로그 출력