Androidアプリ全体のデフォルトのフォントファミリーを設定する方法


282

アプリでRoboto lightフォントを使用しています。フォントを設定するにはandroid:fontFamily="sans-serif-light"、すべてのビューにを追加する必要があります。Robotoフォントをアプリ全体のデフォルトのフォントファミリーとして宣言する方法はありますか?私はこのようにしてみましたが、うまくいかなかったようです。

<style name="AppBaseTheme" parent="android:Theme.Light"></style>

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

2
これはあなたを助けるかもしれません:stackoverflow.com/a/16883281/1329733
Jacob R

2
あなたは今アンドロイドスタジオでXML 3.0からカスタムフォントを指定することができますdeveloper.android.com/guide/topics/ui/look-and-feel/...

回答:


289

答えはイエスです。

TextViewButtonクラスのグローバルRobotoライト:

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="android:buttonStyle">@style/RobotoButtonStyle</item>
</style>

<style name="RobotoTextViewStyle" parent="android:Widget.TextView">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="RobotoButtonStyle" parent="android:Widget.Holo.Button">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

リストthemes.xmlから目的のスタイルを選択し、元のスタイルに基づいてカスタムスタイルを作成するだけです。最後に、スタイルをアプリケーションのテーマとして適用します。

<application
    android:theme="@style/AppTheme" >
</application>

Robotoのような組み込みフォントでのみ機能しますが、それが問題でした。カスタムフォント(アセットから読み込まれるなど)の場合、このメソッドは機能しません。

編集08/13/15

AppCompatテーマを使用している場合は、必ずandroid:プレフィックスを削除してください。例えば:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="buttonStyle">@style/RobotoButtonStyle</item>
</style>

buttonStyleandroid:プレフィックスは含まれませんが、プレフィックスをtextViewStyle含める必要があることに注意してください。


4
どこsans-serif-lightから価値を得ましたか?fontFamilyどこかに有効な値のリストはありますか?私はドキュメントだけでなく、Androidソースのテーマおよびスタイルファイルも調べましたが、何も見つかりません。
クリストファーペリー

34
これはAPIレベル16でのみ可能です。「android:fontFamily」という名前はレベル16以上にのみ存在します。たとえば、API 14でもそれを行う方法はありますか?
Lorenzo Barbagli 2013

3
@LorenzoBarbagli、次のことが確認でき書道
Braisギャバン

10
カスタムフォントがある場合はどうすればよいですか?
Rohit Tigga

2
はい、アプリ全体にカスタムフォントも追加したいと思います。どうやってやるの ?。最初の回答で提案されているように、TextViewをオーバーライドしてすべてのTextViewを置き換える必要がありますか
John

144

Android Oreoのリリースにより、サポートライブラリを使用してこの目標を達成できます。

  1. サポートライブラリ> = 26.0.0がある場合は、アプリのbuild.gradleをチェックインします。
  2. font」フォルダをリソースフォルダに追加し、そこにフォントを追加します
  3. アプリのメインスタイルでデフォルトのフォントファミリーを参照します。

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
       <item name="android:fontFamily">@font/your_font</item>
       <item name="fontFamily">@font/your_font</item> <!-- target android sdk versions < 26 and > 14 if theme other than AppCompat -->
    </style>

詳細については、https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.htmlを確認してください


9
API 26+を対象とする場合、これは受け入れられる方法です。Support Libraryを使用する場合は、android:接頭辞を削除してください
webo80

2
プレフィックスなしのバージョンのみを使用する場合は問題ありません。接頭辞が付いたものは、API <26の場合は無視されます
webo80

2
これはどこでもフォントを設定するわけではありません...たとえば、から派生したスタイルがある場合Base.TextAppearance.AppCompat、それはそこでは使用されません。
Ixx

3
@Ixx、これらのスタイルをオーバーライドする方法も?
プリモジュKralj

2
api <26を対象とする場合は、AppCompatTextViewも使用することを忘れないでください
Codelicious '12

37

アプリのフォントを変更するには、次の手順に従います。

  1. resディレクトリ内に新しいディレクトリを作成し、それを呼び出しますfont
  2. フォント.ttf / .otfをフォントフォルダー内に挿入します。フォント名が小文字とアンダースコアのみであることを確認してください。
  3. 内部res-> values-> styles.xml内部<resources>-> <style>フォントを追加します<item name="android:fontFamily">@font/font_name</item>

ここに画像の説明を入力してください

これで、すべてのアプリテキストが、追加した泉にあるはずです。


8
カスタムフォントを使用しているときに、通常のフォントと共に太字フォントを追加するにはどうすればよいですか?
Rajbir Shienh

これはAPIレベル26以上でのみ機能しますが、API 21以下はどうですか?
zulkarnainシャー

34

以下の更新を読む

新しいフォントを埋め込むことで同じ問題が発生し、ついにTextViewを拡張して内部にtypefontを設定して動作させることができました。

public class YourTextView extends TextView {

    public YourTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public YourTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public YourTextView(Context context) {
        super(context);
        init();
    }

    private void init() {
        Typeface tf = Typeface.createFromAsset(context.getAssets(),
            "fonts/helveticaneue.ttf");
        setTypeface(tf);
    }
}

すべての要素で、後でTextView要素をからに変更する必要があります。また、EclipseでUIクリエーターを使用すると、TextViewが正しく表示されない場合があります。私のために働く唯一のものでした...

更新

最近では、リフレクションを使用して、TextViewを拡張せずにアプリケーション全体の書体を変更しています。このSO投稿をチェックしてください

アップデート2

APIレベル26以降、使用可能な「サポートライブラリ」で利用可能

android:fontFamily="@font/embeddedfont"

詳細情報:XMLのフォント


25
これは解決策ではありません。TextViewだけでなく、さまざまなビューを使用しています。フォントを一度設定したら忘れてしまいたい。さらに、コードはすべてのTextViewに対して新しいオブジェクトを作成します。少なくともアセットからフォントを読み込むために、フィールドを静的として宣言します。
tomrozb 2013年

2
...まあ、この場合に非常にうまく機能する検索と置換機能があります
longi

1
これはうまくいきません。getContext()変数が静的な場合は呼び出すことができません。シングルトンのような方法で実装する必要があります。そうしないと、現在のコードはコンパイルできません。
tomrozb 2015年

1
最後のコミットを元に戻しました。
longi '19年

1
@tomrozb:D私が気づいたのは、私が最後に行った高速な変更は、あなたのコメントによるものでした!十分なポイントがあるので、コード例を自分で最適化することができます。それ以外の場合は、数年後にはこのトピックについて話しますが、誰もスマートフォンを気にしなくなります;)
longi

8

このコード行をres / value / styles.xmlに追加します

<item name="android:fontFamily">@font/circular_medium</item>

スタイル全体はそのようになります

<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>
    <item name="android:fontFamily">@font/circular_medium</item>
</style>

「circular_medium」を自分のフォント名に変更します。


6

パフォーマンスについて話さなくても、カスタムフォントの場合、すべてのビューを再帰的にメソッドループにして、TextViewの場合は書体を設定できます。

public class Font {
    public static void setAllTextView(ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setAllTextView((ViewGroup) child);
            } else if (child instanceof TextView) {
                ((TextView) child).setTypeface(getFont());
            }
        }
    }

    public static Typeface getFont() {
        return Typeface.createFromAsset(YourApplicationContext.getInstance().getAssets(), "fonts/whateverfont.ttf");
    }
}

すべてのアクティビティで、setContentViewの後に現在のViewGroupを渡して完了です。

ViewGroup group = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
Font.setAllTextView(group);

フラグメントについては、同様のことを行うことができます。


1
素晴らしい音ですが、recyclerViewコンテンツでどのように機能させるのでしょうか。
Srujan Barai

私はこれを試しました。レンダリングするには重すぎます。recyclerView地獄のように減速します。
Srujan Barai 2017

リストビューではまったく推奨されません。このトリックは、静的ビューをコーディングする時間を節約するためだけのものです。
アレンチャン

5

アプリ全体でこれを行う別の方法は、この回答に基づいてリフレクションを使用することです

public class TypefaceUtil {
    /**
     * Using reflection to override default typefaces
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE
     * OVERRIDDEN
     *
     * @param typefaces map of fonts to replace
     */
    public static void overrideFonts(Map<String, Typeface> typefaces) {
        try {
            final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
            field.setAccessible(true);
            Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
            if (oldFonts != null) {
                oldFonts.putAll(typefaces);
            } else {
                oldFonts = typefaces;
            }
            field.set(null, oldFonts);
            field.setAccessible(false);
        } catch (Exception e) {
            Log.e("TypefaceUtil", "Can not set custom fonts");
        }
    }

    public static Typeface getTypeface(int fontType, Context context) {
        // here you can load the Typeface from asset or use default ones
        switch (fontType) {
            case BOLD:
                return Typeface.create(SANS_SERIF, Typeface.BOLD);
            case ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.ITALIC);
            case BOLD_ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.BOLD_ITALIC);
            case LIGHT:
                return Typeface.create(SANS_SERIF_LIGHT, Typeface.NORMAL);
            case CONDENSED:
                return Typeface.create(SANS_SERIF_CONDENSED, Typeface.NORMAL);
            case THIN:
                return Typeface.create(SANS_SERIF_MEDIUM, Typeface.NORMAL);
            case MEDIUM:
                return Typeface.create(SANS_SERIF_THIN, Typeface.NORMAL);
            case REGULAR:
            default:
                return Typeface.create(SANS_SERIF, Typeface.NORMAL);
        }
    }
}

次に、フォントをオーバーライドしたいときはいつでも、メソッドを呼び出して、次のようにタイプフェイスのマップを与えることができます。

Typeface regular = TypefaceUtil.getTypeface(REGULAR, context);
Typeface light = TypefaceUtil.getTypeface(REGULAR, context);
Typeface condensed = TypefaceUtil.getTypeface(CONDENSED, context);
Typeface thin = TypefaceUtil.getTypeface(THIN, context);
Typeface medium = TypefaceUtil.getTypeface(MEDIUM, context);
Map<String, Typeface> fonts = new HashMap<>();
fonts.put("sans-serif", regular);
fonts.put("sans-serif-light", light);
fonts.put("sans-serif-condensed", condensed);
fonts.put("sans-serif-thin", thin);
fonts.put("sans-serif-medium", medium);
TypefaceUtil.overrideFonts(fonts);

完全な例のチェック

これは、以前のバージョンのAndroid SDK 21以降でのみ機能します。完全な例を確認してください


5

このlibを使用して、成績ファイルでコンパイルしてください

complie'me.anwarshahriar:calligrapher:1.0'

メインアクティビティのonCreateメソッドで使用します

Calligrapher calligrapher = new Calligrapher(this);
calligrapher.setFont(this, "yourCustomFontHere.ttf", true);

これは、そのための最もエレガントな超高速の方法です。


2

これは私のプロジェクトの仕事です、ソースhttps://gist.github.com/artem-zinnatullin/7749076

Asset Folder内にfontsディレクトリを作成し、カスタムフォントをfontsディレクトリにコピーします。例では、trebuchet.ttfを使用しています。

TypefaceUtil.javaクラスを作成します。

import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;

import java.lang.reflect.Field;
public class TypefaceUtil {

    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {

        }
    }
}

styles.xmlでテーマを編集し、以下に追加

<item name="android:typeface">serif</item>

My styles.xmlの例

<resources>

    <!-- 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>
        <item name="android:typeface">serif</item><!-- Add here -->
    </style>


    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowActionBarOverlay">true</item>
        <item name="android:windowFullscreen">true</item>
    </style>
</resources>

最後に、アクティビティまたはフラグメントのonCreate呼び出しTypefaceUtil.java

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TypefaceUtil.overrideFont(getContext(), "SERIF", "fonts/trebuchet.ttf");
    }

0

Androidは、アプリ全体にフォントを適用するためのサポートをあまり提供していません(この問題を参照)。アプリ全体のフォントを設定するには、4つのオプションがあります。

  • オプション1:リフレクションを適用してシステムフォントを変更する
  • オプション2:カスタムフォントが必要なビューごとにカスタムビュークラスを作成してサブクラス化する
  • オプション3:現在の画面のビュー階層を走査するビュークローラーを実装する
  • オプション4:サードパーティのライブラリを使用します。

これらのオプションの詳細については、こちらをご覧ください


0

私はこの質問がかなり古いことを知っていますが、良い解決策を見つけました。基本的には、この関数にコンテナーレイアウトを渡すと、サポートされているすべてのビューにフォントが適用され、子レイアウトで再帰的に循環します。

public static void setFont(ViewGroup layout)
{
    final int childcount = layout.getChildCount();
    for (int i = 0; i < childcount; i++)
    {
        // Get the view
        View v = layout.getChildAt(i);

        // Apply the font to a possible TextView
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Apply the font to a possible EditText
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Recursively cicle into a possible child layout
        try {
            ViewGroup vg = (ViewGroup) v;
            Utility.setFont(vg);
            continue;
        }
        catch (Exception e) { }
    }
}

0

アプリの書体を、、または(カスタムフォントではなく)に設定するだけnormalsans、これを行うことができます。serifmonospace

テーマを定義し、android:typeface属性を使用したい書体に設定しますstyles.xml

<resources>

    <!-- custom normal activity theme -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- other elements -->
        <item name="android:typeface">monospace</item>
    </style>

</resources>

AndroidManifest.xmlファイル内のアプリ全体にテーマを適用します。

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application
        android:theme="@style/AppTheme" >
    </application>
</manifest>

androidリファレンス


あなたはそれがうまくいくのですか?Androidドキュメントによると、「次の定数値のいずれかである必要があります:ノーマル、サン、セリフ、モノスペース」。
tomrozb 2016年

1
ああ、そうですね...そうです...結局質問が理解できませんでした:xアプリ全体でモノスペースフォント(カスタムではない)を使用したいと思っていたので、それが機能しているのを見て、これを投稿しましたここで…………私の答えは、似たようなことをしたい他の人にとってまだ役に立つかもしれないと思うので、それを編集してここに残します。…………大丈夫です反対票を蓄積します。指摘してくれてありがとう
Eric

@Dave Cruiseさん、モノスペースでのみ機能しますか?私はそれをモノスペースについてのみテストしました...そして何も....それで確信が持てません...しかし、ドキュメントによると、それは「通常」、「サン」および「セリフ」でも機能するはずです。 .i書体はフォントよりも一般的だと思うので、それを使用してアプリのフォントを「コンソール」などの特定のフォントに設定することはできません。
エリック

@エリックいや。私も分からない。モノスペースは魅力のように機能しますが、通常、サン、セリフには運がありません。
Dave Cruise

0

このライブラリを試してください。軽量で実装が簡単です

https://github.com/sunnag7/FontStyler

<com.sunnag.fontstyler.FontStylerView
              android:textStyle="bold"
              android:text="@string/about_us"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:paddingTop="8dp"
              app:fontName="Lato-Bold"
              android:textSize="18sp"
              android:id="@+id/textView64" />

-7

答えはノーです、あなたはできません。アプリケーション全体にカスタムフォントを設定することは可能ですか?を参照してください 詳細については。

そこ回避策はありますが、行では何も「ここでのコードの1行とすべての私のフォントがないであろう、この代わりのこと」。

(GoogleとAppleに感謝します)。カスタムフォントには場所がありますが、アプリ全体を簡単に置き換えることができれば、Comic Sansアプリケーションの世界全体が作成されます)


41
あなたの解説に完全に同意しないでください。フォントをグローバルに設定するのは簡単です。必要な種類の回避策を必要とするものではありません。「Comic Sans」アプリケーションを回避するかどうかは、Google / Appleではなく、世界中の開発者/設計者次第です。
LocalPCGuy 2014年

4
一貫性>ファンシーなデザイン。
Martin Marconcini、2014年

14
ただし、一貫性<機能。聖書のヘブライ語を表示するアプリを開発しています。Androidデバイスにあるすべての標準フォント(最新のAndroid Lフォントを含む)は、カンチレーションマークをレンダリングするというひどい仕事をします(そして、それらは改善されていますが、母音マークについては平凡な仕事をしています)。アプリ全体でカスタムフォントを使用する必要があり、必要なすべてのビューを使用するために必要なコードを多く記述しなければなりませんでした。
テッドホップ、2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.