sourcecode

어플리케이션 전체에 커스텀 폰트를 설정할 수 있습니까?

copyscript 2022. 7. 30. 18:14
반응형

어플리케이션 전체에 커스텀 폰트를 설정할 수 있습니까?

앱 전체에 특정 글꼴을 사용해야 합니다.같은 내용의 .ttf 파일이 있습니다.응용 프로그램 시작 시 이 글꼴을 기본 글꼴로 설정하고 응용 프로그램의 다른 위치에서 사용할 수 있습니까?설정 시 레이아웃 XML에서 어떻게 사용합니까?

네, 반성하고 있습니다. 조작은, 다음의 회답에 근거해 실시합니다.

(주의: 커스텀 폰트를 지원하지 않는 경우의 회피책이므로, 이 상황을 변경하고 싶은 경우는, 여기에서 Android문제를 업 투표해 주세요).주의: 그 문제에 대해 "나도"라는 코멘트를 남기지 마십시오.그것을 개시한 모든 사람은, 그 시점에서 전자 메일을 받습니다.그러니까 그냥 '스타'로 불러주세요.

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride {

    public static void setDefaultFont(Context context,
            String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.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();
        }
    }
}

그런 다음 응용 프로그램클래스 등 몇 가지 기본 글꼴을 오버로드해야 합니다.

public final class Application extends android.app.Application {
    @Override
    public void onCreate() {
        super.onCreate();
        FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
        FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
    }
}

같은 폰트 파일을 사용하고 있는 경우는, 이 기능을 개선해, 1 회만 로드할 수도 있습니다.

1개만 이 있습니다.를 들어, 1개만 덮어씁니다."MONOSPACE"그런 다음 해당 글꼴 서체 응용 프로그램을 전체로 강제하는 스타일을 설정합니다.

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

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:typeface">monospace</item>
    </style>
</resources>

API 21 Android 5.0

효과가 것 같던데, 않는 것 요.android:Theme.Material.Light.

이 테마가 중요하지 않은 경우 다음과 같은 오래된 테마를 사용합니다.

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>

Android에는 커스텀 폰트를 위한 훌륭한 라이브러리가 있습니다.서예

여기 그것의 사용 방법의 샘플이 있습니다.

Gradle에서는 다음 행을 앱의 build.gradle 파일에 넣어야 합니다.

dependencies {
    compile 'uk.co.chrisjenx:calligraphy:2.2.0'
}

그런 다음 수업시간을 연장해서Application다음 코드를 적습니다.

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                        .setDefaultFontPath("your font path")
                        .setFontAttrId(R.attr.fontPath)
                        .build()
        );
    }
} 

액티비티 클래스에서는 onCreate 전에 다음 메서드를 입력합니다.

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}

매니페스트 파일은 절대로 다음과 같습니다.

<application
   .
   .
   .
   android:name=".App">

모든 액티비티가 폰트로 바뀝니다!심플하고 깔끔해요!

전체 어플리케이션에서는 동작하지 않지만 액티비티에서는 동작하며 다른 액티비티에서도 재사용할 수 있습니다.다른 뷰를 지원하기 위해 @FR073N 덕분에 코드를 업데이트했습니다. 문제에 잘 모르겠습니다.Buttons,RadioGroups 확장되어 있기 에, 등TextView잘 작동해야 합니다.매우 해킹적이고 성능이 현저히 저하될 수 있기 때문에 반사 사용을 위한 부울 조건을 추가했습니다.

주의: 지적한 바와 같이 동적 콘텐츠에서는 작동하지 않습니다. 때문에 이 을 '이렇게 하다'라고 할 수 onCreateView ★★★★★★★★★★★★★★★★★」getView이치노

/**
 * Recursively sets a {@link Typeface} to all
 * {@link TextView}s in a {@link ViewGroup}.
 */
public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{
    if (mContainer == null || mFont == null) return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children.
    for (int i = 0; i < mCount; ++i)
    {
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView)
        {
            // Set the font if it is a TextView.
            ((TextView) mChild).setTypeface(mFont);
        }
        else if (mChild instanceof ViewGroup)
        {
            // Recursively attempt another ViewGroup.
            setAppFont((ViewGroup) mChild, mFont);
        }
        else if (reflect)
        {
            try {
                Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
                mSetTypeface.invoke(mChild, mFont); 
            } catch (Exception e) { /* Do something... */ }
        }
    }
}

이 기능을 사용하려면 다음과 같은 작업을 수행합니다.

final Typeface mFont = Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf"); 
final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, mFont);

도움이 됐으면 좋겠다.

요약:

옵션 1: 반사 기능을 사용하여 글꼴 적용(WestonRoger Huang의 답변 조합):

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride { 

    public static void setDefaultFont(Context context,
            String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(),
                fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    } 

    protected static void replaceFont(String staticTypefaceFieldName,final Typeface newTypeface) {
        if (isVersionGreaterOrEqualToLollipop()) {
            Map<String, Typeface> newMap = new HashMap<String, Typeface>();
            newMap.put("sans-serif", newTypeface);
            try {
                final Field staticField = Typeface.class.getDeclaredField("sSystemFontMap");
                staticField.setAccessible(true);
                staticField.set(null, newMap);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            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();
            } 
        }
    }

} 

응용 프로그램 클래스의 사용:

public final class Application extends android.app.Application {
    @Override 
    public void onCreate() { 
        super.onCreate(); 
        FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
        FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
    } 
} 

글꼴 응용 프로그램을 전체로 강제하는 스타일을 설정합니다(lovefish 기준).

롤리팝 전:

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

롤리팝(API 21):

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:textAppearance">@style/CustomTextAppearance</item>
   </style>

   <style name="CustomTextAppearance">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

옵션 2:글꼴을 사용자 정의할 필요가 있는 모든 보기를 하위 분류합니다.ListView, EditTextView, Button 등 (팔라니 답변):

public class CustomFontView extends TextView {

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

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

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

private void init() { 
    if (!isInEditMode()) {
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
        setTypeface(tf);
    } 
} 

옵션 3: 현재 화면의 뷰 계층을 통과하는 View Crawler를 구현합니다.

Variation #1 (Tom's answer):

public static final void setAppFont(ViewGroup mContainer, Typeface mFont, boolean reflect)
{ 
    if (mContainer == null || mFont == null) return;

    final int mCount = mContainer.getChildCount();

    // Loop through all of the children. 
    for (int i = 0; i < mCount; ++i)
    { 
        final View mChild = mContainer.getChildAt(i);
        if (mChild instanceof TextView)
        { 
            // Set the font if it is a TextView. 
            ((TextView) mChild).setTypeface(mFont);
        } 
        else if (mChild instanceof ViewGroup)
        { 
            // Recursively attempt another ViewGroup. 
            setAppFont((ViewGroup) mChild, mFont);
        } 
        else if (reflect)
        { 
            try { 
                Method mSetTypeface = mChild.getClass().getMethod("setTypeface", Typeface.class);
                mSetTypeface.invoke(mChild, mFont); 
            } catch (Exception e) { /* Do something... */ }
        } 
    } 
} 

사용방법:

final ViewGroup mContainer = (ViewGroup) findViewById(
android.R.id.content).getRootView();
HomeActivity.setAppFont(mContainer, Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf"));

Variation #2 : https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere

옵션 4: 서드파티 Lib Callegraphy를 사용합니다.

개인적으로 Option #4를 추천합니다.두통이 많이 줄어들기 때문입니다.

API 21 Android 5.0에 대한 weston의 답변을 개선하고 싶습니다.

원인

API 21에서 대부분의 텍스트 스타일은 다음과 같은 fontFamily 설정을 포함합니다.

<style name="TextAppearance.Material">
     <item name="fontFamily">@string/font_family_body_1_material</item>
</style>

기본 Roboto Regular 글꼴이 적용됩니다.

<string name="font_family_body_1_material">sans-serif</string>

Android:fontFamily가 Android:typeface 속성(참조)보다 우선 순위가 높기 때문에 원래 답변은 monospace 글꼴을 적용하지 못합니다.주제 사용.Holo.*는 Android:fontFamily 설정이 없기 때문에 유효한 회피책입니다.

솔루션

안드로이드 5.0 이후 시스템 서체를 정적 변수 서체로 전환했다.sSystemFontMap(참조)은 동일한 반사 기술을 사용하여 대체할 수 있습니다.

protected static void replaceFont(String staticTypefaceFieldName,
        final Typeface newTypeface) {
    if (isVersionGreaterOrEqualToLollipop()) {
        Map<String, Typeface> newMap = new HashMap<String, Typeface>();
        newMap.put("sans-serif", newTypeface);
        try {
            final Field staticField = Typeface.class
                    .getDeclaredField("sSystemFontMap");
            staticField.setAccessible(true);
            staticField.set(null, newMap);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    } else {
        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();
        }
    }
}

매우 간단합니다... 1. 사용자 지정 글꼴을 다운로드하여 자산에 넣습니다.그리고 텍스트 뷰에 대해 다음과 같이 하나의 클래스를 작성합니다.여기서 나는 futura 글꼴을 사용했습니다.

public class CusFntTextView extends TextView {

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

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

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

private void init() {
    if (!isInEditMode()) {
        Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "Futura.ttf");
        setTypeface(tf);
    }
}

}

xml로 다음 작업을 수행합니다.

 <com.packagename.CusFntTextView
        android:id="@+id/tvtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"         
        android:text="Hi Android"           
        android:textAppearance="?android:attr/textAppearanceLarge"
      />

TextView등의 컨트롤을 확장하는 것도 추천합니다만, 폰트는 컨스트럭트로 설정하는 것을 검토해 두는 것이 좋습니다.

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

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

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

protected void init() {
    setTypeface(Typeface.createFromAsset(getContext().getAssets(), AppConst.FONT));
}

Weston과 Roger Huang의 "테마"를 주제로 한 API 21 이상의 Android 롤리팝에 대한 답변을 개선하고 싶습니다.AppCompat"을 클릭합니다.

Android 4.4 이하

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

오버(동일한) API 5.0

<resources>
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
    </style>

   <!-- Application theme. -->
   <style name="AppTheme" parent="AppBaseTheme">
       <item name="android:textAppearance">@style/CustomTextAppearance</item>
   </style>

   <style name="CustomTextAppearance">
       <item name="android:typeface">monospace</item>
   </style>
</resources>

그리고 FontsOverride util 파일은 weston의 답변과 동일합니다.다음 전화기로 테스트했습니다.

Nexus 5(안드로이드 5.1 프라이머리 안드로이드 시스템)

ZTE V5(안드로이드 5.1 CM12.1)

샤오미 노트(안드로이드 4.4 MIUI6)

HUWAI C8850(안드로이드 2.3.5 불명)

훌륭한 솔루션은, https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere 를 참조해 주세요.

BaseActivity에서 액티비티를 확장하고 해당 메서드를 작성하기만 하면 됩니다.또, 다음의 설명에 따라서 글꼴을 캐시 하는 것이 좋습니다.https://stackoverflow.com/a/16902532/2914140


조사 후 삼성 갤럭시 탭 A(안드로이드 5.0)에서 동작하는 코드를 작성했습니다.Weston 코드와 Roger Huang 코드 및 https://stackoverflow.com/a/33236102/2914140 사용.Lenovo Tab 2 A10-70L에서도 테스트 완료(동작하지 않음).차이를 알아보기 위해 여기에 '만화 산스' 글꼴을 삽입했습니다.

import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class FontsOverride {
    private static final int BOLD = 1;
    private static final int BOLD_ITALIC = 2;
    private static final int ITALIC = 3;
    private static final int LIGHT = 4;
    private static final int CONDENSED = 5;
    private static final int THIN = 6;
    private static final int MEDIUM = 7;
    private static final int REGULAR = 8;

    private Context context;

    public FontsOverride(Context context) {
        this.context = context;
    }

    public void loadFonts() {
        Map<String, Typeface> fontsMap = new HashMap<>();
        fontsMap.put("sans-serif", getTypeface("comic.ttf", REGULAR));
        fontsMap.put("sans-serif-bold", getTypeface("comic.ttf", BOLD));
        fontsMap.put("sans-serif-italic", getTypeface("comic.ttf", ITALIC));
        fontsMap.put("sans-serif-light", getTypeface("comic.ttf", LIGHT));
        fontsMap.put("sans-serif-condensed", getTypeface("comic.ttf", CONDENSED));
        fontsMap.put("sans-serif-thin", getTypeface("comic.ttf", THIN));
        fontsMap.put("sans-serif-medium", getTypeface("comic.ttf", MEDIUM));
        overrideFonts(fontsMap);
    }

    private void overrideFonts(Map<String, Typeface> typefaces) {
        if (Build.VERSION.SDK_INT == 21) {
            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", "Cannot set custom fonts");
            }
        } else {
            try {
                for (Map.Entry<String, Typeface> entry : typefaces.entrySet()) {
                    final Field staticField = Typeface.class.getDeclaredField(entry.getKey());
                    staticField.setAccessible(true);
                    staticField.set(null, entry.getValue());
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    private Typeface getTypeface(String fontFileName, int fontType) {
        final Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/" + fontFileName);
        return Typeface.create(tf, fontType);
    }
}

전체 응용 프로그램에서 코드를 실행하려면 응용 프로그램과 같은 일부 클래스에서 다음을 작성해야 합니다.

    new FontsOverride(this).loadFonts();

'자산' 안에 '글꼴' 폴더를 만들고 필요한 글꼴을 넣습니다.간단한 순서는, https://stackoverflow.com/a/31697103/2914140 를 참조해 주세요.

또한 Lenovo 디바이스는 서체 값을 잘못 받습니다.대부분의 경우 글꼴을 반환합니다.정상, 때로는 무효입니다.TextView가 굵은 글씨(xml 파일 레이아웃)인 경우에도 마찬가지입니다.여기를 참조해 주세요.TextView isBold는 항상 NORMAL을 반환합니다.이렇게 하면 화면의 텍스트는 항상 굵은 글씨나 이탤릭체가 아닌 회귀 글꼴로 표시됩니다.그래서 PD의 버그인 것 같아요.

자마린을 위해 일합니다.안드로이드:

클래스:

public class FontsOverride
{
    public static void SetDefaultFont(Context context, string staticTypefaceFieldName, string fontAssetName)
    {
        Typeface regular = Typeface.CreateFromAsset(context.Assets, fontAssetName);
        ReplaceFont(staticTypefaceFieldName, regular);
    }

    protected static void ReplaceFont(string staticTypefaceFieldName, Typeface newTypeface)
    {
        try
        {
            Field staticField = ((Java.Lang.Object)(newTypeface)).Class.GetDeclaredField(staticTypefaceFieldName);
            staticField.Accessible = true;
            staticField.Set(null, newTypeface);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

응용 프로그램 구현:

namespace SomeAndroidApplication
{
    [Application]
    public class App : Application
    {
        public App()
        {

        }

        public App(IntPtr handle, JniHandleOwnership transfer)
            : base(handle, transfer)
        {

        }

        public override void OnCreate()
        {
            base.OnCreate();

            FontsOverride.SetDefaultFont(this, "MONOSPACE", "fonts/Roboto-Light.ttf");
        }
    }
}

스타일:

<style name="Theme.Storehouse" parent="Theme.Sherlock">
    <item name="android:typeface">monospace</item>
</style>

Android O에서는 XML에서 직접 정의할 수 있게 되어 버그가 종료되었습니다!

자세한 내용은 여기를 참조

TL;DR:

먼저 프로젝트에 글꼴을 추가해야 합니다.

다음으로 다음과 같이 글꼴 패밀리를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>

마지막으로 레이아웃 또는 스타일로 글꼴을 사용할 수 있습니다.

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/lobster"/>

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

맛있게 드세요!

루트 뷰를 전달하면 각 레이아웃에서 함수 호출을 1개씩 호출하여 각 레이아웃의 커스텀 글꼴을 하나씩 설정할 수 있습니다.먼저, 이와 같은 글꼴 오브젝트에 액세스하기 위한 singelton 접근 방식을 만듭니다.

 public class Font {
    private static Font font;
    public Typeface ROBO_LIGHT;

    private Font() {

    }

    public static Font getInstance(Context context) {
        if (font == null) {
            font = new Font();
            font.init(context);
        }
        return font;

    }

    public void init(Context context) {

        ROBO_LIGHT = Typeface.createFromAsset(context.getAssets(),
                "Roboto-Light.ttf");
    }

}

위 클래스에서 다른 글꼴을 정의할 수 있습니다.이제 글꼴을 적용할 글꼴 도우미 클래스를 정의합니다.

   public class FontHelper {

    private static Font font;

    public static void applyFont(View parentView, Context context) {

        font = Font.getInstance(context);

        apply((ViewGroup)parentView);

    }

    private static void apply(ViewGroup parentView) {
        for (int i = 0; i < parentView.getChildCount(); i++) {

            View view = parentView.getChildAt(i);

//You can add any view element here on which you want to apply font 

            if (view instanceof EditText) {

                ((EditText) view).setTypeface(font.ROBO_LIGHT);

            }
            if (view instanceof TextView) {

                ((TextView) view).setTypeface(font.ROBO_LIGHT);

            }

            else if (view instanceof ViewGroup
                    && ((ViewGroup) view).getChildCount() > 0) {
                apply((ViewGroup) view);
            }

        }

    }

}

위의 코드에서는 textView와 EditText에만 글꼴을 적용하고 있으며, 마찬가지로 다른 뷰 요소에도 글꼴을 적용할 수 있습니다.root View 그룹의 ID를 위의 apply 글꼴 메서드에 전달하기만 하면 됩니다.예를 들어 레이아웃은 다음과 같습니다.

<RelativeLayout 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:orientation="vertical"
    android:id="@+id/mainParent"
    tools:context="${relativePackage}.${activityClass}" >

    <RelativeLayout
        android:id="@+id/mainContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/homeFooter"
        android:layout_below="@+id/edit" >

        <ImageView
            android:id="@+id/PreviewImg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/abc_list_longpressed_holo"
            android:visibility="gone" />

        <RelativeLayout
            android:id="@+id/visibilityLayer"
            android:layout_width="match_parent"
            android:layout_height="fill_parent" >

            <ImageView
                android:id="@+id/UseCamera"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true"
                android:src="@drawable/camera" />

            <TextView
                android:id="@+id/tvOR"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/UseCamera"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="20dp"
                android:text="OR"
                android:textSize="30dp" />

            <TextView
                android:id="@+id/tvAND"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="20dp"
                android:text="OR"
                android:textSize="30dp" />

</RelativeLayout>

위의 레이아웃에서 루트 부모 ID는 "Main Parent" 입니다.이것으로 글꼴을 적용합니다.

public class MainActivity extends BaseFragmentActivity {

    private EditText etName;
    private EditText etPassword;
    private TextView tvTitle;
    public static boolean isHome = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       Font font=Font.getInstance(getApplicationContext());
        FontHelper.applyFont(findViewById(R.id.mainParent),          getApplicationContext());
   }    
}

건배 :)

TextView를 확장하고 XML 레이아웃 내에서 또는 TextView가 필요한 곳이라면 언제든지 커스텀 TextView를 사용할 것을 권장합니다.에서 TextView를 .setTypeface

@Override
public void setTypeface(Typeface tf, int style) {
    //to handle bold, you could also handle italic or other styles here as well
    if (style == 1){
        tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans700.otf");
    }else{
        tf = Typeface.createFromAsset(getContext().getApplicationContext().getAssets(), "MuseoSans500.otf");
    }
    super.setTypeface(tf, 0);
}

Tom의 솔루션은 잘 작동하지만 TextView 및 EditText에서만 작동합니다.

대부분의 뷰(RadioGroup, TextView, Checkbox...)를 커버하는 방법을 만들었습니다.

protected void changeChildrenFont(ViewGroup v, Typeface font){
    for(int i = 0; i < v.getChildCount(); i++){

        // For the ViewGroup, we'll have to use recursivity
        if(v.getChildAt(i) instanceof ViewGroup){
            changeChildrenFont((ViewGroup) v.getChildAt(i), font);
        }
        else{
            try {
                Object[] nullArgs = null;
                //Test wether setTypeface and getTypeface methods exists
                Method methodTypeFace = v.getChildAt(i).getClass().getMethod("setTypeface", new Class[] {Typeface.class, Integer.TYPE});
                //With getTypefaca we'll get back the style (Bold, Italic...) set in XML
                Method methodGetTypeFace = v.getChildAt(i).getClass().getMethod("getTypeface", new Class[] {});
                Typeface typeFace = ((Typeface)methodGetTypeFace.invoke(v.getChildAt(i), nullArgs));
                //Invoke the method and apply the new font with the defined style to the view if the method exists (textview,...)
                methodTypeFace.invoke(v.getChildAt(i), new Object[] {font, typeFace == null ? 0 : typeFace.getStyle()});
            }
            //Will catch the view with no such methods (listview...)
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

이 메서드는 XML로 설정된 보기 스타일(굵은 글씨, 이탤릭체...)을 가져와 있는 경우 적용합니다.

ListView에서는 항상 어댑터를 만들고 getView 내에서 글꼴을 설정합니다.

현재 뷰 계층의 뷰에 서체를 할당하는 클래스를 작성하고 현재 서체 속성을 기반으로 했습니다(굵은 글씨, 일반, 원하는 경우 다른 스타일을 추가할 수 있습니다).

public final class TypefaceAssigner {

public final Typeface DEFAULT;
public final Typeface DEFAULT_BOLD;

@Inject
public TypefaceAssigner(AssetManager assetManager) {
    DEFAULT = Typeface.createFromAsset(assetManager, "TradeGothicLTCom.ttf");
    DEFAULT_BOLD = Typeface.createFromAsset(assetManager, "TradeGothicLTCom-Bd2.ttf");
}

public void assignTypeface(View v) {
    if (v instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) v).getChildCount(); i++) {
            View view = ((ViewGroup) v).getChildAt(i);
            if (view instanceof ViewGroup) {
                setTypeface(view);
            } else {
                setTypeface(view);
            }
        }
    } else {
        setTypeface(v);
    }
}

private void setTypeface(View view) {
    if (view instanceof TextView) {
        TextView textView = (TextView) view;
        Typeface typeface = textView.getTypeface();
        if (typeface != null && typeface.isBold()) {
            textView.setTypeface(DEFAULT_BOLD);
        } else {
            textView.setTypeface(DEFAULT);
        }
    }
}
}

이제 onViewCreated 또는 onCreateView의 모든 fragment, onCreate의 모든 액티비티 및 getView 또는 newView의 모든 뷰 어댑터에서 다음 명령을 실행합니다.

typefaceAssigner.assignTypeface(view);

build.gradle 3.0.0 이후를 사용하는 api 26에서는 res에 글꼴디렉토리를 생성하여 이 행을 자신의 스타일에 사용할 수 있습니다.

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

build.gradle 변경에 대해서는 build.gradle 의존관계에서 사용합니다.

classpath 'com.android.tools.build:gradle:3.0.0'

마침내 구글은 이 문제의 심각성을 깨닫고(UI 컴포넌트에 커스텀 폰트를 적용) 깨끗한 해결책을 고안했습니다.

먼저 라이브러리 26+를 지원하도록 업데이트해야 합니다(gradle{4.0+}, Android studio도 업데이트해야 할 수 있습니다). 그런 다음 font라는 새로운 리소스 폴더를 만들 수 있습니다.이 폴더에 글꼴 리소스(.tff,...)를 넣을 수 있습니다.그런 다음 기본 앱을 덮어쓰고 커스텀 폰트를 강제로 삽입해야 합니다.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:fontFamily">@font/my_custom_font</item>
</style>

주의: 16보다 오래된 API를 가진 기기를 지원하려면 Android 대신 앱 네임스페이스를 사용해야 합니다!

API 21 Android 5.0에 대한 weston의 답변도 개선했으면 합니다.

삼성 s5에서도 DEFAULT 글꼴 사용 시 동일한 문제가 발생하였습니다.(다른 글꼴에서는 정상적으로 동작하고 있습니다)

각 Textview 또는 Button에 대해 XML 파일의 서체("sans")를 설정하여 작업을 수행할 수 있었습니다.

<TextView
android:layout_width="match_parent"
android:layout_height="39dp"
android:textColor="@color/abs__background_holo_light"
android:textSize="12sp"
android:gravity="bottom|center"
android:typeface="sans" />

및 My Application Class:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
    TypefaceUtil.overrideFont(getApplicationContext(), "SANS_SERIF",
    "fonts/my_font.ttf");
    }
}

도움이 됐으면 좋겠다.

솔루션은 상황에 따라서는 올바르게 동작하지 않습니다.
그래서 나는 그것을 확장한다.

FontsReplacer.java

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        FontsReplacer.replaceFonts(this);
        super.onCreate();
    }

}

https://gist.github.com/orwir/6df839e3527647adc2d56bfadfaad805

서예는 꽤 잘 쓰이지만 글꼴 패밀리에는 다른 무게(굵은 글씨, 이탤릭체 등)를 지원하지 않기 때문에 나에게는 적합하지 않습니다.

그래서 커스텀 뷰를 정의하고 커스텀 폰트 패밀리를 적용할 수 있는 Fontain을 시도했습니다.

Fontain을 사용하려면 앱 모듈 build.gradle에 다음 항목을 추가해야 합니다.

compile 'com.scopely:fontain:1.0.0'

그런 다음 일반 TextView를 사용하는 대신 FontTextView를 사용해야 합니다.

대문자 및 굵은 글씨로 표시된 FontTextView의 예:

 <com.scopely.fontain.views.FontTextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/black"
            android:textColor="@android:color/white"
            android:textSize="11dp"
            android:gravity="center"
            android:id="@+id/tv1"
            app:font_family="myCustomFont"
            app:caps_mode="characters"
            app:font_weight="BOLD"/>
package com.theeasylearn.demo.designdemo;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class MyButton extends TextView {

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

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

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

    private void init() {

            Typeface tf =
                    Typeface.createFromAsset(
                            getContext().getAssets(), "angelina.TTF");
            setTypeface(tf);

    }

}

TextViews의 기본 글꼴 패밀리를 변경하려면 앱 테마에서 textViewStyle을 덮어씁니다.

fontFamily에서 사용자 지정 글꼴을 사용하려면 지원 라이브러리에 있는 글꼴 리소스를 사용하십시오.

이 기능은 Android 26에 추가되었지만 supportlib을 통해 이전 버전으로 역보도되었습니다.

https://developer.android.com/guide/topics/resources/font-resource.html https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html#using-support-lib

Android Oreo 및 지원 라이브러리(26.0.0)가 출시되었기 때문에 쉽게 할 수 있습니다.다른 질문에서 이 답변을 참조하십시오.

기본적으로 최종 스타일은 다음과 같습니다.

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

서예3도서관코더월의 게시물이 혼합된 것을 최종 결과물로 발견했습니다.

네, 어플리케이션 전체에 폰트를 설정할 수 있습니다.

이를 위한 가장 쉬운 방법은 원하는 글꼴을 응용 프로그램과 패키징하는 것입니다.

이를 수행하려면 프로젝트 루트에 자산/폴더를 만들고 글꼴(TrueType, 즉 TTF 형식으로)을 자산에 넣기만 하면 됩니다.

예를 들어 자산/글꼴/생성하여 TTF 파일을 넣을 수 있습니다.

public class FontSampler extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
TextView tv=(TextView)findViewById(R.id.custom);

Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf");
tv.setTypeface(face);
}
}

언급URL : https://stackoverflow.com/questions/2711858/is-it-possible-to-set-a-custom-font-for-entire-of-application

반응형