Android에서 전체 애플리케이션에 대한 사용자 지정 글꼴을 설정하는 방법은 무엇입니까?


82

Android 애플리케이션에서 사용자 지정 글꼴을 설정할 수 있습니까?

나는 여기 에 게시 된 것을 시도했지만 내 extends Application수업이 어디에 있는지 모르겠습니다 ...

도움이 필요하세요?

편집하다:

다음을 시도했습니다.

  • 자산 폴더를 추가하고 여기에 표시된대로 내부에 글꼴을 삽입합니다.

여기에 이미지 설명 입력

  • 다음에서 확장되는 새 클래스 추가 Application

  • AndroidManifest.xml.

  • 나는 내 스타일로 가서 그것을 추가했습니다.

MyApp.java :

public class MyApp extends Application {
  @Override
  public void onCreate() {
     super.onCreate();
    FontsOverride.setDefaultFont(this, "DEFAULT", "raleway_regular.ttf");
    //  This FontsOverride comes from the example I posted above
  }
  }

AndroidManifest.xml :

<application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true"
      android:name=".MyApp"
      android:theme="@style/AppTheme">
     ....

styles.xml :

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

하지만 내 글꼴이 여전히 변하지 않습니다.

그런 다음 MyApp클래스가 호출됩니다. 하지만 내 글꼴에는 영향을주지 않습니다 ...

EDIT2 : 버튼에 사용자 정의 스타일을 설정 한 후 버튼이 사용자 정의 글꼴을 적용한다는 것을 깨달았습니다. 내 사용자 정의 버튼 스타일은 다음과 같습니다.

<style name="MyButtonStyle" parent="Widget.AppCompat.Button">
    <item name="textAllCaps">false</item>
    <item name="android:textAllCaps">false</item>
</style>

그리고 지금의 모습은 다음과 같습니다.

여기에 이미지 설명 입력

그래서 : 내 버튼은 스타일을 적용하지만 TextView. 내 사용자 정의 글꼴이 응용 프로그램의 모든 항목에 적용되지 않는 이유에 대한 아이디어가 있습니까?


질문에 제공 한 링크는 문제에 정말 도움이됩니다.
Androider 2015

내 솔루션이 거기에 있다고 생각합니다 ...하지만 Application에서 확장되는 클래스를 만들 때 내 클래스가 사용되지 않는다고해서 작동하도록 만들 수 없습니다 ...
Sonhja

내 답변에 더 많은 링크를 확인하세요. 도움이되는 것 같습니다. 한 가지 더 내 첫 번째 링크가 정말 더 좋습니다. 감사합니다
Androider

답변:


49

수업 작성

public class MyApp extends Application{
// Put the onCreate code as you obtained from the post link you reffered
}

이제 다음은 응용 프로그램 태그에 대한 AndroidManifest.xml에 응용 프로그램 클래스의 이름을 지정하는 것입니다. 이 경우는 MyApp입니다.

<application
android:name=".MyApp"
...
>
...
</application>

따라서 App이 열릴 때마다 MyApp 클래스의 onCreate 메소드가 호출되고 글꼴이 설정됩니다.

assets / fonts / your_font_file.ttf 아래에 Put 글꼴 파일 업데이트

이 행을 애플리케이션 클래스 (MyApp)의 onCreate 메소드 아래에 놓으십시오.

TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/your_font_file.ttf");

TypefaceUtil의 소스 파일

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     *
     * @param context                    to work with assets
     * @param defaultFontNameToOverride  for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {

        final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Map<String, Typeface> newMap = new HashMap<String, Typeface>();
            newMap.put("serif", customFontTypeface);
            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 defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
                defaultFontTypefaceField.setAccessible(true);
                defaultFontTypefaceField.set(null, customFontTypeface);
            } catch (Exception e) {
                Log.e(TypefaceUtil.class.getSimpleName(), "Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
            }
        }
    }
}

이제 style.xml 파일을 업데이트하십시오.

매니페스트 파일에 활동에 포함 된 스타일을 아래 줄에 넣으십시오.

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

도움이 되었기를 바랍니다


테스트중인 Android OS 버전을 알려주세요. 나는 우리가 어떤 더 tweeks을해야 롤리팝 관찰 한
니틴 MESTA을

Lollipop 및 이전 Android 버전에 대한 솔루션은 다음 링크를 확인하십시오. ( stackoverflow.com/a/36206275/2268466 )
blueware

이 토스트 메시지, 경고 대화 상자에서 모든 응용 프로그램의 글꼴을 변경, 나는이에 사용자 지정 글꼴 싶지 않아
아딜

1
많은 제조업체가 사용자가 설정에서 시스템 전체의 글꼴을 변경할 수 있도록 허용하고 있습니다. 변경 사항이 프로그래밍 방식으로 설정 한 글꼴 유형도 재정의합니까?
Bhuro

82

편집하다

uk.co.chrisjenx:calligraphyLib는 최신 안드로이드 버전에 대해 더 이상 유지되지 않습니다. 대안은 이제 https://github.com/InflationX/Calligraphy입니다.

dependencies {
    implementation 'io.github.inflationx:calligraphy3:3.1.1'
    implementation 'io.github.inflationx:viewpump:2.0.3'
}

자산에 사용자 정의 글꼴 추가 /

용법

기본 글꼴

#onCreate () 메서드의 Application 클래스에서 CalligraphyConfig를 사용하여 기본 글꼴을 정의하고 ViewPump 빌더에 추가 한 CalligraphyInterceptor에 전달합니다.

@Override
public void onCreate() {
    super.onCreate();
    ViewPump.init(ViewPump.builder()
        .addInterceptor(new CalligraphyInterceptor(
                new CalligraphyConfig.Builder()
                    .setDefaultFontPath("fonts/Roboto-RobotoRegular.ttf")
                    .setFontAttrId(R.attr.fontPath)
                    .build()))
        .build());
    //....
}

컨텍스트에 삽입 : 활동 컨텍스트를 래핑합니다.

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

커스텀 스타일

<style name="TextViewCustomFont">
    <item name="fontPath">fonts/RobotoCondensed-Regular.ttf</item>
</style>

테마

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item>
</style>

<style name="AppTheme.Widget"/>

<style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView">
    <item name="fontPath">fonts/Roboto-ThinItalic.ttf</item>
</style>

Developers Below Solution


android : Calligraphy
다음은 사용 방법에 대한 샘플입니다.

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()
                );
            }
        } 

자산 / "새 디렉토리" "글꼴"(아래 참조)을 만들어야하므로 해당 코드에서 "글꼴 경로"는 "fonts / SourceSansPro-Regular.ttf"여야합니다. ( "/ fonts .."또는 "assets .."가 아닌 "fonts ..."일뿐입니다.)

그리고 액티비티 클래스에서이 메서드를 onCreate 앞에 두십시오.

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

마지막으로 매니페스트 파일은 다음과 같아야합니다.

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

그리고 전체 활동을 글꼴로 변경합니다! 간단하고 깨끗합니다!

자산에서 새 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 "글꼴"이라고합니다. 파인더에서 .ttf글꼴 파일을 거기에 넣으십시오 .

여기에 이미지 설명 입력

또한 attrs.xml에 두 줄 아래에 추가하는 것을 잊지 마십시오 .attrs.xml 파일이 없으면 values.xml에 새 파일을 만듭니다.

 <attr format="string" name="fontPath"/> 
    <item name="calligraphy_tag_id" type="id"/>

나는 ttf를 사용하고 있지만 .otf도 작동하고 자산 폴더에 넣는 가장 좋은 위치에 있다고 확신합니다.
인 Rajesh Nasit

이를 확장 응용 프로그램 클래스 CalligraphyConfig.initDefault (new CalligraphyConfig.Builder () .setDefaultFontPath ( "fonts / GOTHAM-MEDIUM.ttf") .setFontAttrId (R.attr.fontPath) .build ()); 또한 그나마 values.xml <ATTR 형식 = "문자열"이름 = "글꼴 경로"/>에서 두 줄 아래에 추가하는 것을 잊었다 <항목 이름 = 유형 = "ID"/ "calligraphy_tag_id">
인 Rajesh Nasit

안녕 @rajesh! "편집"을 클릭하고 훌륭한 답변에 추가해야합니다! 맞습니다 . .ttf 파일 이어야 합니다. 죄송합니다.
Fattie 2017-04-13

1
가능한 한 최대 조각을 사용할 수 있습니다. 그래서 그 활동의 수가 줄어들 것입니다.
인 Rajesh Nasit

1
나는 간단한 기본 클래스를 정의 - @Pawan 그것을 한 단계를 수행하는 attachBaseContext(..)구현을 한 다음 모든 (I 그 사용자 지정 글꼴을 원하는) 내 프로젝트 활동 클래스는 기본 클래스 확장
진 보

63

내가 한 것은 :

1 : RES 폴더에 "새 리소스 디렉터리"를 추가하고, 주어진 드롭 다운에서 "글꼴"로 리소스 유형을 선택하고, 새 디렉터리 이름을 "글꼴"로 지정하고 저장합니다. 새로운 리소스 디렉토리

2 : 방금 만든 FONT 폴더에 "custom_font.ttf"를 추가했습니다.

3 : STYLES.XML의 애플리케이션 기본 테마에 내 사용자 정의 글꼴 추가

STYLES.XML

끝난.


4
글꼴 패밀리도 만들어야합니다. 그 후 그것은 나를 위해 일했습니다. 여기에 세부 정보 : developer.android.com/guide/topics/ui/look-and-feel/…
keybee

글꼴 모음을 만들지 않고도 저에게 효과적이었습니다. 그러나 Gradle 버전> 3을 사용하고 도구를 빌드하고 27> @keybee
Numanqmr로

글꼴 패밀리 없이도 나를 위해 훌륭하게 일했습니다
Julian Alberto

프로그래밍 방식으로 변경하는 방법을 알고 있습니까?
majov

@majov는 #Rajeesh로 위의 답변을 확인하십시오. 도움이 될 것입니다!
Numanqmr

12

set / 2017에 게시 된 Android 개발자 공식 유튜브 채널이 여기 에 있으므로 이제 Android SDK로 할 수 있습니다 .

API 레벨 26 (Android 8 Oreo) 이상이 필요합니다.

글꼴 파일을 res/font폴더 에 넣고 속성이 TextView있는 특정 파일 이 필요한 경우 참조하기 만하면 android:fontFamily됩니다.

전체 앱에 기본 글꼴을 사용하려면 간단히

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

당신의 styles.xml

원하는 경우 Android Studio 및 이동 중에도 사용자 지정 글꼴을 다운로드 할 수 있습니다. 이 모든 것은 위의 비디오에서 자세히 찾을 수 있습니다.


이 옵션은 API 26 이상용입니다. 16 세 이상 아님
Perfect Square

API 23 + 수정은 어떻습니까?
Raju yourPepe 19-01-22

12

Android는 지원 라이브러리 26+에서 API 레벨 14 이상을 지원하는 더 간단하고 최상의 솔루션을 제공합니다. XML의 글꼴 글꼴 군 옵션 도 지원합니다 . 필수 가져 오기 : implementation "com.android.support:support-compat:<26+ version>"

다음의 간단한 단계를 따르시면 아무런 문제없이 앱에 글꼴 패밀리가 적용됩니다.

  1. res 안에 글꼴 디렉토리 만들기
  2. 글꼴 파일 안에 붙여 넣기 글꼴을
  3. 글꼴 폴더를 마우스 오른쪽 버튼으로 클릭하고 새로 만들기> 글꼴 리소스 파일로 이동합니다. 새 리소스 파일 창이 나타납니다.
  4. 다음 속성 추가
<?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>
  1. 위의 xml 파일에서. 지원 라이브러리를 사용하는 경우에만 을 사용 하십시오 . 그렇지 않으면 앱이 API 레벨 26 이상을 대상으로하는 경우 android 를 사용할 수 있습니다 .
  2. 이제 styles.xml로 이동하여 기본 스타일의 줄 아래에 넣으십시오.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. 중요 : 지원 라이브러리를 사용하는 경우에만 AppCompatActivity를 사용하십시오 .
  4. 또는 아래에서 프로그래밍 방식으로 서체를 설정하십시오.

    view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
    

이 방법은 현재 Android 글꼴 리소스 기능에 적합합니다. 감사.
azwar_akbar

2

당신이 사용하고있는 것 같다 android:fontFamily대신에 android:typeface당신을에서 styles.xml.

교체 시도

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

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

1
내 응용 프로그램과 어떻게 연결합니까? 누가 그것으로부터 확장됩니까?
Sonhja 2015

확장 Application하면 단순히 애플리케이션 클래스의 하위 클래스를 만드는 것 Application입니다. 따라서 연결할 필요가 없습니다.
Suhas

한 번도 사용되지 않았다는 것은 무엇입니까?
Suhas

동일한 SO 게시물에서 제안한대로 앱 파일 <item name="android:typeface">default</item>내부 <style name="AppTheme" parent="AppBaseTheme">에 줄 을 추가 했습니까 res -> values -> styles.xml?
Suhas

예, 또한 작동하지 않습니다. 그것은 내가 편집에 넣은 것입니다 ... :(
Sonhja

2

첫 번째 주제를 따르면 작동합니다. 여기

네, 반성합니다. 이것은 작동합니다 ( 이 답변을 기반으로 함 ).

(참고 : 이것은 사용자 정의 글꼴에 대한 지원이 부족하기 때문에 해결 방법이므로이 상황을 변경하려면 별표를 실행하여 여기에서 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");
    }
}

또는 동일한 글꼴 파일을 사용하는 경우이를 개선하여 한 번만로드 할 수 있습니다.

그러나 "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>

1

기본 폴더에 자산 폴더를 만들고 그 안에 글꼴 폴더를 추가합니다. 글꼴 폴더에 .ttf 파일을 추가하십시오.

앱 테마에 다음을 추가하십시오.

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

TypefaceUtil로 클래스 만들기

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

import java.lang.reflect.Field;

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     * @param context to work with assets
     * @param defaultFontNameToOverride for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    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) {
            Log.e("Can not set","Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

애플리케이션 클래스 또는 Launcher 활동에서 호출하십시오.

        TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf

1
  1. 처음에는 프로젝트 리소스 이름 res을 마우스 오른쪽 버튼으로 클릭 한 다음 new옵션에서 선택 Android Resource Directory하고 font양식을 선택 하고 Resource type확인을 누르면 글꼴을 배치 할 글꼴 디렉토리가 생성됩니다.

여기에 이미지 설명 입력

  1. .ttf거기에 글꼴 파일을 넣으십시오 .

여기에 이미지 설명 입력

  1. 다음 경로에있는 프로젝트 스타일 파일로 이동하여 다음 res/values/styles.xml 과 같은 스타일을 추가하십시오.

    <style name="SansSerifFont">
        <item name="android:fontFamily">sans-serif</item>
    </style>
    
    <style name="OpenSansFont">
        <item name="android:fontFamily">@font/open_sans</item>
    </style>
    
    <style name="IranianSansFont">
        <item name="android:fontFamily">@font/iranian_sans</item>
    </style>
    
    <style name="BYekanFont">
        <item name="android:fontFamily">@font/b_yekan</item>
    </style>
    
    <style name="DroidArabicFont">
        <item name="android:fontFamily">@font/droid_arabic</item>
    </style>
    
  2. 코드로 이동하여 전체 앱 글꼴을 변경하기 위해 다음과 같은 클래스를 작성하십시오.

    public class AppFontManager {
    
        private AppCompatActivity appCompatActivity;
    
        public static final String SANS_SERIF_APP_FONT = "sans_serif";
        public static final String B_YEKAN_APP_FONT = "b_yekan";
        public static final String DROID_ARABIC_APP_FONT = "droid_arabic";
        public static final String IRANIAN_SANS_APP_FONT = "iranian_sans";
        public static final String OPEN_SANS_APP_FONT = "open_sans";
    
        public AppAppearanceManager(AppCompatActivity appCompatActivity) {
            this.appCompatActivity = appCompatActivity;
        }
    
        public void setFont(String fontName){
    
            switch (fontName){
    
                case SANS_SERIF_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.SansSerifFont, true);
                    break;
                }
    
                case B_YEKAN_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.BYekanFont, true);
                    break;
                }
    
                case DROID_ARABIC_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.DroidArabicFont, true);
                    break;
                }
    
                case IRANIAN_SANS_APP_FONT:{
                appCompatActivity.getTheme().applyStyle(R.style.IranianSansFont, true);
                    break;
                }
    
                case OPEN_SANS_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.OpenSansFont, true);
                    break;
                }
            }
        }
    }
    

    활동 마다 글꼴을 별도로 설정해야 하므로보다 깔끔한 코드를 위해 클래스를 작성하는 것이 좋습니다.

  3. 그런 다음 onCreate 활동 전에 클래스 메서드를 호출합니다 super.onCreate(savedInstanceState).

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        new AppAppearanceManager(this).setFont(APP_DEFAULT_FONT);
        super.onCreate(savedInstanceState);
    // Do you stuff there...
    }
    

    런타임 중에 글꼴을 변경하려면 선택한 글꼴 SharedPreferences등을 작성한 다음 setFont위와 같은 모든 활동에 선택한 글꼴을 전달하십시오 .


0

먼저 사용자 정의하려는 뷰를 재정의하는 새 클래스를 만듭니다. (예 : 사용자 정의 서체가있는 버튼을 원하십니까? 확장 Button). 예를 들면 :

public class CustomButton extends Button {
    private final static int ROBOTO = 0;
    private final static int ROBOTO_CONDENSED = 1;

    public CustomButton(Context context) {
        super(context);
    }

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        parseAttributes(context, attrs); //I'll explain this method later
    }

    public CustomButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        parseAttributes(context, attrs);
    }
}

이제 XML 문서가없는 경우 아래에 XML 문서를 res/values/attrs.xml추가하고 다음을 추가합니다.

<resources>
    <!-- Define the values for the attribute -->
    <attr name="typeface" format="enum">
        <enum name="roboto" value="0"/>
        <enum name="robotoCondensed" value="1"/>
    </attr>

    <!-- Tell Android that the class "CustomButton" can be styled, 
         and which attributes it supports -->
    <declare-styleable name="CustomButton">
        <attr name="typeface"/>
    </declare-styleable>
</resources>

자, 이제 그 parseAttributes()방법으로 이전 의 방법으로 돌아 갑시다 .

private void parseAttributes(Context context, AttributeSet attrs) {
    TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);

    //The value 0 is a default, but shouldn't ever be used since the attr is an enum
    int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);

    switch(typeface) {
        case ROBOTO: default:
            //You can instantiate your typeface anywhere, I would suggest as a 
            //singleton somewhere to avoid unnecessary copies
            setTypeface(roboto); 
            break;
        case ROBOTO_CONDENSED:
            setTypeface(robotoCondensed);
            break;
    }

    values.recycle();
}

이제 모든 설정이 완료되었습니다. 무엇이든에 대해 더 많은 속성을 추가 할 수 있지만 (굵게, 기울임 꼴 등 typefaceStyle에 대해 다른 속성을 추가 할 수 있음) 이제 사용 방법을 살펴 보겠습니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.yourpackage.name.CustomButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me!"
        custom:typeface="roboto" />

</LinearLayout>

xmlns:custom줄은 정말 아무것도 할 수 있지만 규칙은 위에 표시되는 것입니다. 중요한 것은 고유하다는 것이므로 패키지 이름이 사용됩니다. 이제 custom:속성에 접두사를 사용하고 android:Android 속성에 접두사를 사용합니다.

마지막으로, 스타일 ( res/values/styles.xml) 에서 이것을 사용 하려면 선을 추가 하지 않아야 합니다 xmlns:custom. 접두사없이 속성 이름을 참조하십시오.

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>

0

나는 글꼴 재정의도 시도했지만 결국에는 신뢰할 수있는 해결책이 아니며 슬프게도 글꼴 재정의는 그 이상을 필요로합니다. 맞춤 글꼴이있는 Android O가 나올 때까지 기다리거나 타사 라이브러리를 사용할 수 있습니다.

내가 찾은 마지막 해결책은이 라이브러리 Caligraphy 였습니다.이 라이브러리 는 시작하기 쉽고 원하는만큼 글꼴을 사용할 수 있습니다. 소스 코드를 확인하면서 글꼴 재정의가 작동하지 않는 이유를 이해 했으므로 사용할 계획이 없더라도 한 번 읽어 보는 것이 좋습니다.

행운을 빕니다


네 .. 아마도. 어쨌든이 문제의 원인을 찾으면 알려주세요. 정말 감사하겠습니다. 기본 코드를 읽어도 해결책을 찾을 수 없었습니다.
Keivan Esbati

0

아래 코드를 사용해보십시오. 저에게 효과적입니다. 도움이되기를 바랍니다.

public class BaseActivity extends AppCompatActivity {

private Typeface typeace;
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    typeace = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name));
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    overrideFonts(this,getWindow().getDecorView());
}

private void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
         }
        } else if (v instanceof TextView) {
            ((TextView) v).setTypeface(typeace);
        } else if (v instanceof EditText ) {
            ((EditText) v).setTypeface(typeace);
        } else if (v instanceof Button) {
            ((Button) v).setTypeface(typeace);
        }
    } catch (Exception e) {
 }
 }
}

이제이 BaseActivity를 활동으로 확장하거나 사용중인 경우 조각에 대해 동일한 클래스를 만들 수 있습니다.

참고 :-보기 다른 서체를 설정하려면 아래와 같이 프로그래밍 방식으로 설정해야합니다.

private Typeface typeface;
typeface = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name_bold));
tvUserName.setTypeface(typeface);

그러니 한 번 시도해보고 알려주세요.


0

kotlin에 대한 해결 방법은 다음과 같습니다.

솔루션의 요점 https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

1 단계

assets / fonts / your_font_file.ttf 아래에 글꼴 파일을 넣고 TypeFaceUtil이라는 kotlin 클래스를 만듭니다.

   class TypefaceUtil{

    fun overridefonts(context: Context, defaultFontToOverride:String, customFontFileNameInAssets:String){
        try {
            val customTypeface = Typeface.createFromAsset(context.assets,customFontFileNameInAssets)
            val defaultTypefaceField = Typeface::class.java.getDeclaredField(defaultFontToOverride)
            defaultTypefaceField.isAccessible = true
            defaultTypefaceField.set(null,customTypeface)
        }catch (e:Exception){
            Timber.e("Cannot set font $customFontFileNameInAssets instead of $defaultFontToOverride")
        }
    }
}

2 단계 다음에는onCreate

val typefaceUtil = TypefaceUtil()

typefaceUtil.overridefonts(this,"SERIF","fonts/font_file.ttf")

3 단계

당신의 스타일에 이것을 추가하십시오

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

0

응용 프로그램 및 작업에 표시하려면 글꼴 이름이 소문자 여야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.