Androidはワンツーパンチ 三歩進んで二歩下がる

プログラミングやどうでもいい話

【Android開発】xmlファイルでアプリ全体にオリジナルのフォントを適用する(Android4.1 API level 16以降)

カスタムフォントの記事です。
※2019/06/03時点での情報です。

公式サイト

Font resources  |  Android Developers
Fonts in XML  |  Android Developers
Android 8.0 の機能と API  |  Android Developers

この記事の内容を試したサンプルの環境

  • Android Studio 3.4.1
  • Gradle 3.4.1
  • AndroidX appcompat:1.0.2を使用
  • minSdkVersion 16
  • targetSdkVersion 28
  • 実行結果はエミュレータでAndroid4.1, Android6.0, Android9.0で確認

フォントファイルをリソースとして認識させる

Android 8.0 (API level 26) で、追加された機能を使ってフォントを適用します。
以下の公式サイトの引用にもあるように、サポートライブラリ26以上(当然AndroidXもOK)を導入していて
Android 4.1 (API level 16) 以降で実行すれば使えるので
(下記の引用ではAPIバージョン14以降とありますが、こちらでは16以降となっています)、
大抵の環境で使えると思います。

Android 8.0 には、フォントをリソースとして利用できる XML フォント機能が新しく導入されています。
この機能を使うと、フォントをアセットにバンドルする必要はなくなります。
フォントは R ファイルでコンパイルされ、システムで自動的にリソースとして利用できるようになります。
これらのフォントには、新しいリソースタイプ font を使ってアクセスします。
Support Library 26 は、API バージョン 14 以降が実行されている端末で、この機能に対するフルサポートを提供します。
引用元:Android 8.0 の機能と API  |  Android Developers

フォルダを追加する

resフォルダの下にfontフォルダを追加します。
Android Studioresフォルダの上で右クリックメニューを表示して
New -> Folder -> Font Resources Folderを選択します。

フォントファイルを追加する

fontフォルダ配下に.ttf, .ttc, .otf, .xml などのファイルを設置すると、ファイル名がリソースIDとして認識されます。

注意点として

  • fontというフォルダ名である必要があります。
  • ファイル名はAndroidの規則に従い、小文字a-z, 0-9, _で構成されている必要があります。

f:id:sakura_bird1:20190603212050p:plain:w400

フォントリソースにアクセスする

フォントにアクセスするには@font/customfontR.font.customfontのように指定します。

プログラム内でアクセスする場合はgetFont(int)メソッドにリソースのidを渡してフォントを取得します。

Typeface typeface = getResources().getFont(R.font.myfont);
textView.setTypeface(typeface);

アプリ全体にフォントを適用する

アプリのベースとなるスタイルにandroid:fontFamilyを記述します。
AndroidManifest.xmlのApplicationタグの中のthemeのやつです。
新規でプロジェクトを作るとandroid:theme="@style/AppTheme" となっていると思います。

res/values/styles.xml

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <!-- Font style for a whole application project -->
        <item name="android:fontFamily">@font/sawarabimincho_regular</item>
    </style>

個別のViewにフォントを適用する

レイアウトの編集画面からTextViewなどのfontFamilyをフォントファイル名にします。

    <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:fontFamily="@font/mplus_rounded1c_bold"
            android:text="5.この文章はダミーです。この文章はダミーです。この文章はダミーです。"/>

アプリ全体+個別のViewにそれぞれフォントを指定した場合

プロジェクト全体のフォントを指定している場合は、Viewに指定している方が優先されます。
例として、5つのTextViewがあるレイアウトで最初の2つはフォント指定無し、残りの3つは指定ありの場合
最初の2つはプロジェクト全体へのフォント指定が適用され、
残りの3つはそれぞれのViewに指定したフォントが適用されます。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/activity_vertical_margin"
        android:orientation="vertical"
        tools:context=".MainActivity">

    <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:text="1.この文章はダミーです。この文章はダミーです。この文章はダミーです。"/>

    <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:text="2.この文章はダミーです。この文章はダミーです。この文章はダミーです。"/>

    <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:fontFamily="@font/mplus_rounded1c_regular"
            android:text="3.この文章はダミーです。この文章はダミーです。この文章はダミーです。"/>

    <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:fontFamily="@font/mplus_rounded1c_thin"
            android:text="4.この文章はダミーです。この文章はダミーです。この文章はダミーです。"/>

    <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/activity_vertical_margin"
            android:fontFamily="@font/mplus_rounded1c_bold"
            android:text="5.この文章はダミーです。この文章はダミーです。この文章はダミーです。"/>

</LinearLayout>

f:id:sakura_bird1:20190604002856p:plain:w400