전체 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

답변:


289

대답은 '예'입니다.

글로벌 로봇 조명 TextView및 Button클래스 :

<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>

(가) 주 buttonStyle포함하지 않는 android:접두사를하지만, textViewStyle그것을 포함해야합니다.


4
어디에서 sans-serif-light가치 를 얻었 습니까? fontFamily어딘가에 유효한 값 목록이 있습니까? Android 소스의 테마 및 스타일 파일뿐만 아니라 문서를 살펴본 결과 아무것도 찾을 수 없습니다.
— Christopher Perry

34
이것은 API 레벨 16에서만 가능합니다. "android : fontFamily"라는 이름은 16 레벨 이상에서만 존재합니다. 예를 들어 API 14에서도 그렇게 할 수있는 방법이 있습니까?
— Lorenzo Barbagli

3
@LorenzoBarbagli, 당신은 서예
— Brais Gabin

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+를 타겟팅 할 때는 이것이 허용되는 방법이어야합니다. 지원 라이브러리를 사용 하는 경우 android:접두사를 제거하십시오.
— webo80

2
접두사를 사용하지 않는 경우에만 문제가 없습니다. 단지 API <26 무시됩니다 앞에 둔 한
— webo80

2
이것은 어디서나 글꼴을 설정하지 않습니다. 예를 들어 Base.TextAppearance.AppCompat, 에서 파생 된 스타일이있는 경우 에는 사용되지 않습니다.
— Ixx

3
@ Ixx, 그 스타일을 재정의하는 방법?
— Primož Kralj

2
api <26
— Codelicious을

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 shah

34

아래의 업데이트 읽기

새 글꼴을 포함하는 것과 동일한 문제가 발생하여 마침내 TextView를 확장하고 내부에서 글꼴을 설정하는 작업을 수행했습니다.

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-Creator를 사용하면 때로는 TextView가 올바르게 표시되지 않습니다. 나를 위해 일한 유일한 사람이었습니다 ...

최신 정보

요즘에는 TextView를 확장하지 않고 전체 응용 프로그램에서 서체를 변경하기 위해 리플렉션을 사용하고 있습니다. 이 SO 게시물을 확인하십시오

업데이트 2

API 레벨 26부터 '지원 라이브러리'에서 사용 가능

android:fontFamily="@font/embeddedfont"

추가 정보 : XML의 글꼴


25
이것은 해결책이 아닙니다. TextView뿐만 아니라 많은 다른보기를 사용하고 있습니다. 글꼴을 한 번 설정하고 잊고 싶습니다. 또한 코드는 모든 TextView에 대해 새 객체를 만듭니다. 최소한 애셋에서 글꼴을 한 번로드하려면 필드를 정적으로 선언하십시오.
— tomrozb

2
...이 경우에는 정말 잘 작동하는 찾기 및 바꾸기 기능이 있습니다.
— longi

1
작동하지 않습니다. getContext()변수가 정적 일 때는 호출 할 수 없습니다 . 단일 방식으로 구현해야합니다. 그렇지 않으면 현재 코드가 컴파일되지 않습니다.
— tomrozb

1
나는 마지막 커밋을 되 돌렸다.
— longi

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 2016 년

방금 시도했습니다. 렌더링하기에는 너무 무겁습니다. 아래로 둔화 recyclerView지옥 같은합니다.
— Srujan Barai 2016 년

목록보기에는 전혀 권장되지 않지만이 트릭은 정적보기를 코딩하는 시간을 절약하기위한 것입니다.
— Allen Chan

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>

내 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>

마지막으로, Activity 또는 Fragment에서 CreateCreate TypeTypeUtil.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

에 응용 프로그램의 단지 세트 서체로 normal, sans, serif또는 monospace(가 아닌 사용자 정의 글꼴로!), 당신은이 작업을 수행 할 수 있습니다.

테마를 정의하고 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 문서에 따르면 : "정상, sans, serif, monospace 상수 값 중 하나 여야합니다."
— tomrozb

1
오, 알다시피 ... 당신이 맞아 ... 나는 결국 질문을 이해하지 못했다 : x 나는 단지 전체 응용 프로그램이 모노 스페이스 글꼴 (사용자 지정 아님)을 사용하도록하고 싶었고 작동하는 것을 보았 기 때문에 이것을 게시했다. 여기 ...... ... 나는 내 대답이 여전히 비슷한 것을하고 싶은 다른 사람들에게 유용 할 수 있다고 생각합니다 .... 그래서 그것을 편집하고 여기에 남겨 둘 것입니다 ..... 나는 괜찮습니다 투표를 축적합니다. 지적 해 주셔서 감사합니다
— Eric

@Dave Cruise, 모노 스페이스에서만 작동합니까? 나는 단 하나의 공간에 대해서만 테스트했지만 ... 아무것도 .... 확실하지 않습니다 ...하지만 설명서에 따르면 "정상", "산"및 "분리"에서도 작동합니다. .i 서체가 글꼴보다 일반적이라고 생각하므로 앱의 글꼴을 "consolas"와 같은 특정 글꼴로 설정하는 데 사용할 수 없습니다.
— Eric

@ 에릭 네. 나도 몰라 단일 공간은 매력처럼 작동하지만 일반, 산세 또는 세리프에게는 운이 없습니다.
— 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

대답은 '아니요'입니다. 전체 응용 프로그램에 대해 사용자 정의 글꼴을 설정할 수 있습니까?를 참조하십시오 . 자세한 내용은.

이 해결 방법이 있지만의 라인에서 아무것도 "여기에 코드 내 모든 글꼴의 하나 개의 라인은 없을 것 이 아닌 것을 ."

(Google 및 Apple에게 감사드립니다). 사용자 정의 글꼴은 자리가 있지만 앱을 쉽게 대체 할 수있게하면 Comic Sans 응용 프로그램 의 전 세계를 만들 수 있습니다 )


41
당신의 논평에 완전히 동의하지 않습니다. 글꼴을 전역 적으로 설정하는 것은 필요한 해결 방법이 필요한 것이 아니라 사소한 일입니다. Google / Apple이 아닌 "Comic Sans"애플리케이션을 피하는 것은 전 세계 개발자 / 디자이너의 책임입니다.
— LocalPCGuy

4
일관성> 팬시 디자인.
— Martin Marconcini

14
그러나 일관성 <기능성. 우리는 성경 히브리어를 표시하는 앱을 개발합니다. 안드로이드 기기 (최신 안드로이드 L 폰트 포함)에서 발견되는 모든 스톡 폰트는 캔틸 레이션 마크를 렌더링하는 엄청난 작업을 수행합니다. 우리는 앱 전체에 커스텀 글꼴을 사용해야하며, 필요한 모든 뷰를 사용하려면 너무 많은 코드를 작성해야했습니다.
— Ted Hopp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.