Làm thế nào để đặt phông chữ tùy chỉnh cho toàn bộ ứng dụng trong Android?


82

Có thể đặt phông chữ tùy chỉnh trong ứng dụng Android không?

Tôi đã thử những gì được đăng ở đây , nhưng tôi không biết extends Applicationlớp của tôi ở đâu ...

Bất kỳ giúp đỡ?

BIÊN TẬP:

Tôi đã thử những cách sau:

  • Thêm một thư mục nội dung và chèn phông chữ vào bên trong như đã thấy ở đây:

nhập mô tả hình ảnh ở đây

  • Thêm một lớp mới mở rộng từ Application

  • Gọi lớp học mới này từ của tôi AndroidManifest.xml.

  • Tôi đã đi đến phong cách của tôi và thêm nó.

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>

Nhưng phông chữ của tôi vẫn không thay đổi ... bất kỳ ý tưởng nào?

Sau đó, MyApplớp được gọi. Nhưng không ảnh hưởng đến phông chữ của tôi ...

EDIT2: Tôi nhận ra rằng các nút của tôi áp dụng phông chữ tùy chỉnh sau khi tôi đặt kiểu tùy chỉnh cho các nút của mình. Đây là kiểu nút tùy chỉnh của tôi:

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

Và đây là cách nó trông bây giờ:

nhập mô tả hình ảnh ở đây

Vì vậy: nút của tôi đang áp dụng kiểu, nhưng không phải TextView. Bất kỳ ý tưởng nào về lý do tại sao phông chữ tùy chỉnh của tôi không được áp dụng cho tất cả các mục trong ứng dụng?


liên kết bạn cung cấp trong câu hỏi thực sự hữu ích cho vấn đề của bạn.
Androider

Tôi biết, tôi nghĩ rằng giải pháp của tôi là ở đó ... Nhưng khi tôi tạo ra một lớp mà kéo dài từ ứng dụng, tôi không thể làm cho nó làm việc như nó nói lớp học của tôi là không bao giờ được sử dụng ...
Sonhja

kiểm tra thêm một số liên kết trong câu trả lời của tôi, có vẻ hữu ích, một điều nữa là liên kết đầu tiên của tôi thực sự tốt hơn, Cảm ơn
Androider

Câu trả lời:


49

Viết một lớp học

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

bây giờ điều tiếp theo là trong AndroidManifest.xml cho thẻ ứng dụng, đặt tên cho lớp ứng dụng của bạn. Trong trường hợp này, đó là MyApp

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

Vì vậy, bất cứ khi nào Ứng dụng được mở, phương thức onCreate của lớp MyApp sẽ được gọi và phông chữ sẽ được đặt.

Cập nhật Đặt tệp phông chữ dưới nội dung / phông chữ / your_font_file.ttf

Đặt dòng này dưới phương thức onCreate của lớp ứng dụng của bạn (MyApp)

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

Tệp nguồn cho 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);
            }
        }
    }
}

Bây giờ hãy cập nhật tệp style.xml của bạn

đặt dòng bên dưới phong cách của bạn được bao gồm cho hoạt động của bạn trong tệp kê khai

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

Hi vọng điêu nay co ich


Vui lòng cho tôi biết phiên bản hệ điều hành Android của bạn mà bạn đang thử nghiệm. Tôi đã quan sát thấy trong kẹo mút chúng ta cần phải chắc chắn tweeks hơn
Nitin Mesta

Vui lòng kiểm tra đường dẫn sau cho các giải pháp cho Lollipop và các phiên bản Android trước đó: ( stackoverflow.com/a/36206275/2268466 )
blueware

nó thay đổi tất cả phông chữ ứng dụng trong thông điệp bánh mì nướng, hộp thoại cảnh báo, tôi không muốn để phông chữ tùy chỉnh sử dụng trong này
Adil

1
Tôi có nghi ngờ, Nhiều nhà sản xuất cho phép người dùng thay đổi phông chữ trên toàn hệ thống từ cài đặt, Thay đổi đó cũng ghi đè lên loại phông chữ mà chúng tôi đặt theo chương trình?
Bhuro

82

BIÊN TẬP

uk.co.chrisjenx:calligraphyLib không được duy trì nhiều hơn để thay thế phiên bản Android mới nhất hiện là https://github.com/InflationX/Cal Thư pháp

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

Thêm phông chữ tùy chỉnh của bạn vào nội dung /

Sử dụng

Đối với phông chữ mặc định

Xác định phông chữ mặc định của bạn bằng cách sử dụng Cal Thư phápConfig, trong lớp Ứng dụng của bạn trong phương thức #onCreate () và chuyển nó đến Cal Thư phápInterceptor mà bạn thêm vào trình tạo ViewPump của mình.

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

Chèn vào ngữ cảnh: Tóm tắt bối cảnh hoạt động:

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

Phong cách tùy chỉnh

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

Đối với chủ đề

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

Không được các nhà phát triển bên dưới giải pháp duy trì hơn


Có một thư viện tuyệt vời cho các phông chữ tùy chỉnh trong Android: Thư pháp
Đây là một ví dụ về cách sử dụng nó.

Trong Gradle, bạn cần đặt dòng này vào tệp build.gradle của ứng dụng:

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

Và sau đó tạo một lớp mở rộng Ứng dụng và viết mã này:

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

Bạn nên tạo nội dung / "phông chữ" "Thư mục mới" (xem bên dưới), vì vậy trong mã đó, "đường dẫn phông chữ của bạn" phải là "phông chữ / SourceSansPro-Regular.ttf". (Chỉ là "phông chữ ..." không phải "/ phông chữ .." hoặc "tài sản ..")

Và trong lớp hoạt động, hãy đặt phương thức này trước onCreate:

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

Và điều cuối cùng tệp kê khai của bạn sẽ trông như thế này:

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

Và nó sẽ thay đổi toàn bộ hoạt động sang phông chữ của bạn! nó đơn giản và sạch sẽ!

Trên Tài sản, bạn nên nhấp chuột phải vào Thư mục mới, gọi nó là "phông chữ". Trong công cụ tìm kiếm, hãy đặt các .ttftệp phông chữ vào đó.

nhập mô tả hình ảnh ở đây

Cũng đừng quên thêm hai dòng dưới đây trong attrs.xml, nếu bạn không có tệp attrs.xml, hãy tạo tệp mới trong các giá trị.xml

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

Tôi đang sử dụng ttf nhưng tôi khá chắc chắn rằng .otf cũng sẽ hoạt động và vị trí tốt nhất để đặt nó trong thư mục tài sản.
Rajesh Nasit

Đặt điều này vào lớp Ứng dụng mở rộng Cal Thư phápConfig.initDefault (new Cal Thư phápConfig.Builder () .setDefaultFontPath ("fonts / GOTHAM-MEDIUM.ttf") .setFontAttrId (R.attr.fontPath) .build ()); Cũng đừng quên thêm vào bên dưới hai dòng trong giá trị .xml <attr format = "string" name = "fontPath" /> <item name = "calligraphy_tag_id" type = "id" />
Rajesh Nasit

chào @rajesh! bạn nên nhấp vào "Chỉnh sửa" và thêm câu trả lời đó vào câu trả lời tuyệt vời của bạn! bạn nói đúng, nó phải là tệp .ttf , xin lỗi.
Fattie

1
Bạn có thể sử dụng phân mảnh tối đa có thể. Vì vậy, số lượng hoạt động sẽ được giảm xuống.
Rajesh Nasit,

1
@Pawan để làm điều đó một bước - Tôi định nghĩa một lớp cơ sở đơn giản mà attachBaseContext(..)được thực hiện, và sau đó tất cả các lớp học Hoạt động dự án của tôi (mà tôi muốn rằng phông chữ tùy chỉnh) mở rộng mà lớp cơ sở
Gene Bo

63

Tất cả những gì tôi đã làm là:

1: Đã thêm "thư mục tài nguyên mới" vào thư mục RES, LOẠI NGUỒN LỰC đã chọn làm "phông chữ" từ trình đơn thả xuống, đặt tên thư mục mới là "phông chữ" và lưu. HƯỚNG DẪN NGUỒN LỰC MỚI

2: Đã thêm "custom_font.ttf" của tôi vào thư mục FONT vừa tạo.

3: Đã thêm phông chữ tùy chỉnh của tôi trong chủ đề cơ sở ứng dụng trong STYLES.XML

STYLES.XML

LÀM XONG.


4
Bạn cũng phải tạo một họ phông chữ. Sau đó nó đã làm việc cho tôi. Thông tin chi tiết tại đây: developer.android.com/guide/topics/ui/look-and-feel/…
keybee

nó hoạt động cho tôi mà không cần phải tạo một họ phông chữ. Tuy nhiên, tôi đã phải sử dụng phiên bản Gradle> 3 và xây dựng các công cụ và libs hỗ trợ thiết lập để 27> @keybee
Numanqmr

Làm việc rất lớn đối với tôi, thậm chí không có họ phông chữ
Julian Alberto

bạn có biết cách thay đổi nó theo chương trình không?
chuyên ngành

@majov kiểm tra câu trả lời ở trên của #Rajeesh. điều đó sẽ giúp bạn!
Numanqmr

12

Bạn có thể làm điều đó với Android SDK ngay bây giờ, vì kênh youtube chính thức của Nhà phát triển Android được xuất bản vào bộ / 2017 tại đây .

Yêu cầu API cấp 26 (Android 8 Oreo) trở lên.

Bạn chỉ cần đặt tệp phông chữ của mình vào res/fontthư mục và tham chiếu chúng trong thư mục của bạn TextViewtrong trường hợp bạn cần một tệp cụ thể với android:fontFamilythuộc tính.

Nếu bạn muốn có một phông chữ cơ bản trên toàn bộ ứng dụng của mình, chỉ cần đặt

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

trong của bạn styles.xml

Bạn có thể tải xuống phông chữ tùy chỉnh từ Android Studio và khi đang di chuyển nếu muốn. Tất cả những điều này bạn có thể tìm thấy với chi tiết trên video ở trên.


Tùy chọn này dành cho API 26 trở lên. Không phải 16+
Perfect Square

làm thế nào về việc sửa chữa cho API 23 +?
Raju yourPepe

12

Android cung cấp các giải pháp đơn giản hơn và tốt nhất được hỗ trợ trên API cấp 14 bởi Thư viện hỗ trợ 26+. Phông chữ trong XML Nó cũng hỗ trợ tùy chọn họ phông chữ . Nhập bắt buộc: implementation "com.android.support:support-compat:<26+ version>"

Làm theo các bước đơn giản sau và họ phông chữ sẽ được áp dụng trong ứng dụng của bạn mà không gặp bất kỳ trở ngại nào:

  1. Tạo một thư mục phông chữ bên trong res
  2. Dán tệp phông chữ của bạn vào bên trong phông chữ
  3. Bấm chuột phải vào thư mục phông chữ và đi tới Mới> Tệp tài nguyên phông chữ. Cửa sổ Tệp Tài nguyên Mới xuất hiện.
  4. Thêm các thuộc tính sau
<?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. Trong tệp xml ở trên. Chỉ sử dụng ứng dụng để sử dụng thư viện hỗ trợ. Nếu không, bạn có thể sử dụng android nếu ứng dụng của bạn nhắm mục tiêu API cấp 26+.
  2. Bây giờ, hãy truy cập styles.xml của bạn và đặt dòng dưới đây theo phong cách chính của bạn.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. Quan trọng: Chỉ sử dụng AppCompatActivity nếu bạn đang sử dụng thư viện hỗ trợ.
  4. Hoặc sử dụng bên dưới để đặt kiểu chữ theo chương trình

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

Cách này phù hợp với tính năng Tài nguyên Phông chữ của Android hiện tại. Cảm ơn.
azwar_akbar 31-07-19

2

Có vẻ như bạn đang sử dụng android:fontFamilythay vì android:typefacetrong của bạn styles.xml.

Thử thay thế

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

với

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

1
Và làm cách nào để kết nối nó với ứng dụng của tôi? Ai mở rộng từ nó?
Sonhja

Bằng cách mở rộng, Applicationbạn chỉ cần tạo một lớp con của lớp Ứng dụng của bạn Application. Vì vậy, bạn không cần phải kết nối nó.
Suhas

Điều gì nói rằng nó không bao giờ được sử dụng?
Suhas

Bạn cũng đã thêm <item name="android:typeface">default</item>dòng bên trong tệp <style name="AppTheme" parent="AppBaseTheme">Ứng dụng của mình res -> values -> styles.xmlnhư được đề xuất trong cùng một bài đăng SO?
Suhas

Có, và nó cũng không hoạt động. Đó chỉ là những gì tôi đưa vào bản chỉnh sửa của mình ... :(
Sonhja 25/11/15

2

Nếu bạn theo dõi chủ đề đầu tiên, điều này sẽ hoạt động: Tại đây

Có với sự phản ánh. Điều này hoạt động ( dựa trên câu trả lời này ):

(Lưu ý: đây là một cách giải quyết do thiếu hỗ trợ cho các phông chữ tùy chỉnh, vì vậy nếu bạn muốn thay đổi tình huống này, hãy đóng dấu sao để bỏ phiếu cho vấn đề Android tại đây). Lưu ý: Đừng để lại bình luận "tôi cũng vậy" về vấn đề đó, tất cả những ai đã xem nó sẽ nhận được email khi bạn làm điều đó. Vì vậy, chỉ cần "sao" nó vui lòng.

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

Sau đó, bạn cần quá tải một số phông chữ mặc định, ví dụ như trong một lớp ứng dụng:

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

Hoặc tất nhiên nếu bạn đang sử dụng cùng một tệp phông chữ, bạn có thể cải thiện điều này để tải nó chỉ một lần.

Tuy nhiên, tôi có xu hướng chỉ ghi đè một cái, nói "MONOSPACE", sau đó thiết lập một kiểu để buộc ứng dụng phông chữ đó rộng rãi:

<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

Tôi đã điều tra các báo cáo trong các nhận xét rằng nó không hoạt động và có vẻ như không tương thích với chủ đề android: Theme.Material.Light.

Nếu chủ đề đó không quan trọng đối với bạn, hãy sử dụng chủ đề cũ hơn, ví dụ:

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

1

Tạo thư mục tài sản trong thư mục phông chữ folder.add chính trong đó. thêm tệp .ttf của bạn vào thư mục phông chữ.

Thêm phần sau vào Chủ đề ứng dụng của bạn:

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

Tạo lớp dưới dạng 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);
        }
    }
}

Gọi nó trong lớp ứng dụng hoặc trong hoạt động Trình khởi chạy

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

1
  1. Lúc đầu, bạn nên nhấp chuột phải vào tài nguyên dự án của mình, ressau đó từ newtùy chọn chọn Android Resource Directoryvà chọn fontbiểu mẫu Resource typevà nhấn OK, điều này sẽ tạo thư mục phông chữ để đặt phông chữ của bạn vào đó.

nhập mô tả hình ảnh ở đây

  1. Đặt các .ttftệp phông chữ của bạn vào đó.

nhập mô tả hình ảnh ở đây

  1. Đi tới tệp kiểu dự án tồn tại trong đường dẫn sau res/values/styles.xml và thêm các kiểu như vậy:

    <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. Đi tới mã của bạn và viết một lớp như thế này để thay đổi phông chữ toàn bộ ứng dụng:

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

    Bởi vì các phông chữ nên được đặt riêng cho từng hoạt động, tôi thích viết một lớp cho nó để có mã rõ ràng hơn.

  3. Sau đó gọi phương thức lớp trước hoạt động onCreate super.onCreate(savedInstanceState):

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

    Hãy nhớ rằng nếu bạn muốn thay đổi phông chữ trong thời gian chạy , hãy viết phông chữ đã chọn vào SharedPreferenceshoặc v.v., sau đó chuyển phông chữ đã chọn cho tất cả các hoạt động setFontnhư trên.


0

Đầu tiên, tạo một lớp mới ghi đè bất kỳ Chế độ xem nào bạn muốn tùy chỉnh. (ví dụ: muốn có một Nút có kiểu chữ tùy chỉnh? Mở rộng Button). Ví dụ:

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

Bây giờ, nếu bạn chưa có, hãy thêm tài liệu XML bên dưới res/values/attrs.xmlvà thêm:

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

Được rồi, vậy là xong, hãy quay lại parseAttributes()phương pháp trước đó:

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

Bây giờ bạn đã sẵn sàng. Bạn có thể thêm nhiều thuộc tính hơn cho bất kỳ thứ gì (bạn có thể thêm một thuộc tính khác cho typefaceStyle - đậm, nghiêng, v.v.) nhưng bây giờ hãy xem cách sử dụng nó:

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

Các xmlns:customdòng thực sự có thể được bất cứ điều gì, nhưng ước là những gì đang hiển thị ở trên. Điều quan trọng là nó là duy nhất và đó là lý do tại sao tên gói được sử dụng. Bây giờ bạn chỉ cần sử dụng custom:tiền tố cho các thuộc tính của mình và android:tiền tố cho các thuộc tính android.

Một điều cuối cùng: nếu bạn muốn sử dụng nó trong một style ( res/values/styles.xml), bạn không nên thêm xmlns:customdòng. Chỉ cần tham chiếu tên của thuộc tính không có tiền tố:

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

0

Tôi cũng đã thử ghi đè phông chữ nhưng cuối cùng thì đó không phải là một giải pháp đáng tin cậy, đáng buồn là việc ghi đè phông chữ mất nhiều hơn thế. Bạn có thể đợi Android O với phông chữ tùy chỉnh ra mắt hoặc sử dụng thư viện của bên thứ ba.

Giải pháp cuối cùng mà tôi gặp phải là thư viện Caligraphy này , dễ bắt đầu và cho phép bạn sử dụng bao nhiêu phông chữ tùy thích. Trong khi kiểm tra mã nguồn của nó, tôi đã hiểu tại sao chỉ ghi đè phông chữ sẽ không hoạt động vì vậy ngay cả khi bạn không định sử dụng nó, tôi khuyên bạn nên đọc qua một lần ..

Chúc may mắn


Vâng .. có thể. Dù sao hãy cho chúng tôi biết nếu bạn tìm thấy một lý do đằng sau vấn đề này, sẽ thực sự đánh giá cao nó. Tôi không thể tìm thấy giải pháp ngay cả khi đọc các mã cơ bản.
Keivan Esbati

0

Hãy thử mã dưới đây, nó phù hợp với tôi, Hy vọng nó cũng sẽ giúp bạn.

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) {
 }
 }
}

Bây giờ hãy mở rộng BaseActivity này cho bất kỳ Hoạt động nào của bạn hoặc bạn có thể tạo cùng một lớp cho phân đoạn nếu bạn đang sử dụng.

Lưu ý: - Nếu bạn muốn đặt một số kiểu chữ khác nhau của chế độ xem thì bạn phải đặt kiểu chữ đó theo chương trình như bên dưới

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

Vì vậy, hãy thử và cho tôi biết, nếu tôi có thể giúp bạn thêm


0

Một công việc xung quanh cho kotlin sẽ là điều này

Giới thiệu giải pháp https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

Bước một

Đặt tệp phông chữ dưới tài sản / phông chữ / your_font_file.ttf và Tạo một lớp kotlin có tên là TypeFaceUtil

   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")
        }
    }
}

Bước hai Sau đó vào của bạnonCreate

val typefaceUtil = TypefaceUtil()

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

Bước thứ ba

thêm cái này vào phong cách của bạn

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

0

Tên phông chữ nên viết thường để hiển thị trong ứng dụng và công việc.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.