Phông chữ tùy chỉnh và bố cục XML (Android)


174

Tôi đang cố gắng xác định bố cục GUI bằng các tệp XML trong Android. Theo như tôi có thể tìm hiểu, không có cách nào để xác định rằng các widget của bạn nên sử dụng phông chữ tùy chỉnh (ví dụ: bạn đã đặt trong tài sản / phông chữ /) trong các tệp XML và bạn chỉ có thể sử dụng phông chữ được cài đặt hệ thống.

Tôi biết rằng, trong mã Java, tôi có thể thay đổi phông chữ của từng tiện ích bằng cách sử dụng các ID duy nhất. Ngoài ra, tôi có thể lặp lại tất cả các widget trong Java để thực hiện thay đổi này, nhưng điều này có lẽ sẽ rất chậm.

Tôi có những lựa chọn nào khác? Có cách nào tốt hơn để làm cho các widget có giao diện tùy chỉnh không? Tôi đặc biệt không muốn phải thay đổi phông chữ theo cách thủ công cho mọi tiện ích mới tôi thêm.


68
DrDefrost - vui lòng chấp nhận một số câu trả lời, bạn sẽ nhận được nhiều phản hồi hơn trên trang web này.
SK9

1
Đây là một câu hỏi tương tự nữa: stackoverflow.com/questions/9030204/ từ
Vins

Cập nhật ngày 05/2017: "Thư viện hỗ trợ 26.0 Beta cung cấp hỗ trợ cho tính năng Phông chữ trong XML trên các thiết bị chạy Android API phiên bản 14 trở lên." Xem: developer.android.com/preview/features/
Mạnh

Câu trả lời:


220

Bạn có thể mở rộng TextView để đặt phông chữ tùy chỉnh như tôi đã học ở đây .

TextViewPlus.java:

package com.example;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;

public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

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

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface tf = null;
        try {
        tf = Typeface.createFromAsset(ctx.getAssets(), asset);  
        } catch (Exception e) {
            Log.e(TAG, "Could not get typeface: "+e.getMessage());
            return false;
        }

        setTypeface(tf);  
        return true;
    }

}

attrs.xml: (tính bằng res / giá trị)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TextViewPlus">
        <attr name="customFont" format="string"/>
    </declare-styleable>
</resources>

tệp chính:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/res/com.example"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.example.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="saxmono.ttf">
    </com.example.TextViewPlus>
</LinearLayout>

Bạn sẽ đặt "saxmono.ttf" vào thư mục tài sản .

CẬP NHẬT 8/1/13

Có những lo ngại về trí nhớ nghiêm trọng với phương pháp này. Xem bình luận của chedabob bên dưới.


5
Tuy nhiên, điều đó có vẻ tốt, tôi đang gặp lỗi khi tôi cố gắng sử dụng "TextViewPlus" trong tệp main.xml. Tôi nhận được các thông tin sau: - error: Lỗi phân tích cú pháp XML: tiền tố không liên kết - Tiền tố "foo" cho thuộc tính "foo: customFont" được liên kết với loại phần tử "supportLibs.TextViewPlus" không bị ràng buộc.
Majjoodi

79
Một điều cần lưu ý là điều này sẽ tạo ra hàng chục và hàng chục đối tượng TypeFace và ăn hết bộ nhớ. Có một lỗi trong Android trước 4.0 không giải phóng TypeFaces đúng cách. Cách dễ nhất là tạo bộ đệm TypeFace bằng HashMap. Điều này mang lại mức sử dụng bộ nhớ trong ứng dụng của tôi giảm từ 120+ mb xuống còn 18mb. code.google.com/p/android/issues/detail?id=9904
chedabob

7
@Majjoodi: Điều đó thường xảy ra nếu bạn quên thêm không gian tên thứ 2 vào bố cục của mình:xmlns:foo="http://schemas.android.com/apk/res/com.example
Theo

11
RẤT QUAN TRỌNG - Tôi chỉ muốn tăng gấp đôi lời khuyên của chedabob. Trừ khi bạn theo dõi nó, bạn sẽ bị rò rỉ bộ nhớ trong tiền ICS. Có một vài giải pháp, một trong số đó là trong liên kết được cung cấp bởi chedabob, một giải pháp khác có ở đây: stackoverflow.com/questions/8057010/listview-memory-leak . peter - vui lòng cập nhật câu trả lời của bạn - thật tuyệt nhưng chưa hoàn thành
Michał K

1
Làm cách nào để tôi đặt thuộc tính tùy chỉnh này trong tệp kiểu tệp ngoài các thuộc tính văn bản xem khác như chiều rộng và chiều cao?
loeschg

35

Tôi trễ 3 năm cho bữa tiệc :( Tuy nhiên điều này có thể hữu ích cho ai đó có thể vấp ngã khi đăng bài này.

Tôi đã viết một thư viện lưu trữ Kiểu chữ và cũng cho phép bạn chỉ định kiểu chữ tùy chỉnh ngay từ XML. Bạn có thể tìm thấy thư viện ở đây .

Đây là cách bố trí XML của bạn sẽ trông như thế nào, khi bạn sử dụng nó.

<com.mobsandgeeks.ui.TypefaceTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    geekui:customTypeface="fonts/custom_font.ttf" />

Này @ Ragunath-jawahar, làm thế nào tôi có thể nhập thư viện cho một dự án gradle? Tôi đã thử compile 'com.mobsandgeeks:android-typeface-textview:1.0'nhưng điều đó không hiệu quả.
aimango

1
Bạn sẽ cần AAR để có thể sử dụng nó theo cách đó. Nó chưa có ở đó. Bạn có thể sao chép các nguồn và xây dựng dự án Thư viện Android Studio ngay bây giờ.
Ragunath Jawahar

2
Thẻ geekui của bạn đến từ đâu?
sefirosu

3
Từ không gian tên được chỉ định trong thẻ cha -xmlns:geekui="http://schemas.android.com/apk/res-auto"
Ragunath Jawahar

1
@MuhammedRefaat, đúng vậy :)
Ragunath Jawahar

18

Điều này có thể hơi muộn, nhưng bạn cần tạo một lớp singleton trả về kiểu chữ tùy chỉnh để tránh rò rỉ bộ nhớ.

Lớp TypeFace:

public class OpenSans {

private static OpenSans instance;
private static Typeface typeface;

public static OpenSans getInstance(Context context) {
    synchronized (OpenSans.class) {
        if (instance == null) {
            instance = new OpenSans();
            typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf");
        }
        return instance;
    }
}

public Typeface getTypeFace() {
    return typeface;
}
}

TextView tùy chỉnh:

public class NativelyCustomTextView extends TextView {

    public NativelyCustomTextView(Context context) {
        super(context);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

    public NativelyCustomTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        setTypeface(OpenSans.getInstance(context).getTypeFace());
    }

}

Bằng xml:

<com.yourpackage.views.NativelyCustomTextView
            android:id="@+id/natively_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="20dp"
            android:text="@string/natively"
            android:textSize="30sp" /> 

Lập trình:

TextView programmaticallyTextView = (TextView) 
       findViewById(R.id.programmatically_text_view);

programmaticallyTextView.setTypeface(OpenSans.getInstance(this)
                .getTypeFace());

Có vẻ như để làm việc trong thời gian chạy, nhưng nó cũng được cho là làm việc trong nhà thiết kế?
Magnus Johansson

Chắc chắn rồi. Bạn có thể sử dụng như xml. @Magnus
Leonardo Cardoso

Tôi nghĩ rằng bạn hiểu lầm, nó dường như không làm việc trong thiết kế thời gian (Nhà thiết kế preview). (xml! = nhà thiết kế). Nó hoạt động tốt được chỉ định trong tệp bố cục Xml được biên dịch vào thời gian chạy. Dù sao, tôi đang sử dụng tiện ích mở rộng này github.com/danh32/Fontify , hoạt động tốt hơn cho nhu cầu của tôi (nó hỗ trợ nhiều kiểu phông chữ, thông thường, đậm, v.v. cũng như các tên phông chữ khác nhau cũng như các điều khiển khác ngoài TextView)
Magnus Johansson

2
GetTypeFace tạo ra một kiểu chữ mới trên mỗi cuộc gọi ... điều này đánh bại mục đích của singleton. Nó nên có một trường tĩnh được đặt lần đầu tiên khi cuộc gọi được thực hiện và trả về giá trị của trường trong các cuộc gọi tiếp theo.
Steven Pena

1
@chiwai bạn nói đúng! Về câu hỏi đầu tiên nó không cần nó. Về lần thứ hai, nó là một lỗi đánh máy.
Leonardo Cardoso

13

Câu hỏi cũ, nhưng tôi chắc chắn muốn đọc câu trả lời này ở đây trước khi tôi bắt đầu tìm kiếm một giải pháp tốt. Thư pháp mở rộng android:fontFamilythuộc tính để thêm hỗ trợ cho phông chữ tùy chỉnh trong thư mục tài sản của bạn, như vậy:

<TextView 
  android:text="@string/hello_world"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:fontFamily="fonts/Roboto-Bold.ttf"/>

Điều duy nhất bạn phải làm để kích hoạt nó là gắn nó vào Bối cảnh của Hoạt động bạn đang sử dụng:

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

Bạn cũng có thể chỉ định thuộc tính tùy chỉnh của riêng bạn để thay thế android:fontFamily

Nó cũng hoạt động trong các chủ đề, bao gồm cả AppTheme.


8

Sử dụng DataBinding :

@BindingAdapter({"bind:font"})
public static void setFont(TextView textView, String fontName){
 textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName));
}

Trong XML:

<TextView
app:font="@{`Source-Sans-Pro-Regular.ttf`}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

tập tin phông chữ phải ở trong assets/fonts/


7

Nếu bạn chỉ có một kiểu chữ bạn muốn thêm và muốn viết ít mã hơn, bạn có thể tạo một TextView dành riêng cho phông chữ cụ thể của mình. Xem mã dưới đây.

package com.yourpackage;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontTextView extends TextView {
    public static Typeface FONT_NAME;


    public FontTextView(Context context) {
        super(context);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
    public FontTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf");
        this.setTypeface(FONT_NAME);
    }
}

Trong tệp main.xml, bây giờ bạn có thể thêm textView của mình như thế này:

<com.yourpackage.FontTextView
    android:id="@+id/tvTimer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />

làm điều này trên init () và tự lưu 3 lần cuộc gọi tương tự.
ericosg

@ericosg Tôi gặp lỗi này khi sử dụng giải pháp yourthis android.view.InflateException: Dòng tệp nhị phân XML # 9: Lỗi làm tăng lớp com.ascent.adwad.utils.CustomTextView
Sagar Devanga 30/12/14

@SagarDevanga, khó giúp đỡ mà không có thêm thông tin. Có lẽ hãy đưa nó ra xa nhất có thể và đưa ra một câu hỏi mới.
ericosg

7

Cách tốt nhất để làm điều đó Từ bản phát hành xem trước của Android O là cách này
1.) Nhấp chuột phải vào thư mục res và chuyển đến New> thư mục tài nguyên Android .
Cửa sổ Thư mục tài nguyên mới xuất hiện.
2.) Trong danh sách Loại tài nguyên, chọn phông chữ , rồi bấm OK.
3.) Thêm tệp phông chữ của bạn trong thư mục phông chữ . Cấu trúc thư mục bên dưới tạo R.font.dANCE_script, R.font.la_la và R.font.ba_ba.
4.) Nhấp đúp vào tệp phông chữ để xem trước phông chữ của tệp trong trình chỉnh sửa.

Tiếp theo chúng ta phải tạo một họ phông chữ

1.) Nhấp chuột phải vào thư mục phông chữ và đi đến 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.
2.) Nhập tên tệp, rồi bấm OK . XML tài nguyên phông chữ mới mở trong trình soạn thảo.
3.) Đóng gói từng tệp phông chữ, kiểu và thuộc tính trọng lượng trong thành phần thẻ phông. XML sau minh họa thêm các thuộc tính liên quan đến phông chữ trong tài nguyên phông chữ XML:

<?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/hey_regular" />
    <font
    android:fontStyle="italic"
    android:fontWeight="400"
    android:font="@font/hey_bababa" />
</font-family>

Thêm phông chữ vào TextView:

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

Từ tài liệu

Làm việc với các phông chữ

tất cả các bước là chính xác.


1
Câu trả lời tốt nhất! Tên tệp phông chữ phải được viết thường.
Dmitry

Bạn cũng có thể tạo một kiểu tùy chỉnh mà bạn áp dụng cho ứng dụng của mình (trong tệp AndroidManifest) và nó sẽ được trao cho TẤT CẢ các chế độ xem. Thay vì chỉ đặt nó trên một TextView, vì điều này sẽ không ảnh hưởng đến Thanh công cụ.
Goldenmaza

5

Mở rộng TextViewvà cung cấp cho nó một thuộc tính tùy chỉnh hoặc chỉ sử dụng thuộc tính android: tag để chuyển vào Chuỗi bạn muốn sử dụng phông chữ nào. Bạn sẽ cần chọn một quy ước và tuân theo nó, chẳng hạn như tôi sẽ đặt tất cả các phông chữ của mình vào thư mục res / nội dung / phông chữ / để lớp TextView của bạn biết nơi tìm chúng. Sau đó, trong hàm tạo của bạn, bạn chỉ cần đặt phông chữ theo cách thủ công sau siêu cuộc gọi.


4

Cách duy nhất để sử dụng phông chữ tùy chỉnh là thông qua mã nguồn.

Chỉ cần nhớ rằng Android chạy trên các thiết bị có tài nguyên và phông chữ rất hạn chế có thể cần một lượng RAM tốt. Các phông chữ Droid tích hợp được tạo đặc biệt và, nếu bạn lưu ý, có nhiều ký tự và trang trí bị thiếu.


"Chỉ cần nhớ rằng Android chạy trên các thiết bị có nguồn lực rất hạn chế" -> điều này ngày càng trở nên ít hơn. Điện thoại lõi tứ? Có thật không??
Sandy

9
Tôi sẽ làm nhiều hơn để thể hiện sự cân nhắc về bối cảnh câu trả lời của tareqHs, trước nhận xét của bạn sau 2 năm rưỡi.
SK9

Phần đầu tiên trong câu trả lời của bạn có thể đúng khi bạn viết câu trả lời của mình vào năm 2010. Phần sau là superfluoys và bên cạnh quan điểm: Droid rất tệ, bị Google bỏ rơi vào năm 2012 để ủng hộ Roboto. Sự thiếu lựa chọn về kiểu chữ trong Android là một thiếu sót, không phải là một tính năng; iOS đã có nhiều phông chữ có sẵn cho các nhà phát triển kể từ năm 2008 theo các thiết bị nguyên thủy theo tiêu chuẩn ngày nay.
cosmix

Câu trả lời này không còn giá trị.
Martin Konecny

2

Tôi có thể có một câu trả lời đơn giản cho câu hỏi mà không cần mở rộng TextView và triển khai một mã dài.

Mã số:

 TextView tv = (TextView) findViewById(R.id.textview1);
    tv.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf"));

Đặt tệp phông chữ tùy chỉnh trong thư mục tài sản như bình thường và thử điều này. Nó làm việc cho tôi. Tôi chỉ không hiểu tại sao peter đã đưa ra một mã lớn như vậy cho điều đơn giản này hoặc anh ta đã đưa ra câu trả lời của mình trong phiên bản cũ.


2

Cũng có thể được định nghĩa trong xml mà không cần tạo các lớp tùy chỉnh

style.xml

<style name="ionicons" parent="android:TextAppearance">
    <!-- Custom Attr-->
    <item name="fontPath">fonts/ionicons.ttf</item>
</style>

Activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/ionicons"
        android:text=""/>
</LinearLayout>

Một lưu ý nhanh, vì tôi luôn quên không đặt phông chữ ở đâu, phông chữ phải ở bên trong assetsvà thư mục này nằm ở cùng cấp độ ressrctrong trường hợp của tôiassets/fonts/ionicons.ttf

Đã cập nhật bố trí gốc vì phương thức này cần xmlns:app="http://schemas.android.com/apk/res-auto"hoạt động

Cập nhật 2 Quên về một thư viện mà tôi đã cài đặt trước khi gọi là Thư pháp


Điều này không làm việc cho tôi. Khi tôi cố gắng xây dựng điều này, tôi nhận được thông báo lỗi: Lỗi: (49, 5) Không tìm thấy tài nguyên nào khớp với tên đã cho: attr 'fontPath'.
Stef

Hãy thử thêm xmlns:app="http://schemas.android.com/apk/res-auto"vào bố cục gốc của bạn, cũng kiểm tra câu trả lời được cập nhật
Norman784

Lỗi không đến từ tệp XML bố cục mà từ tệp XML kiểu. Có vẻ như nó không 'biết' fontPath là gì.
Stef

Quyền của bạn, quên rằng tôi có một thư viện có tên Calligrapy
Norman784

1

Câu trả lời của Peter là tốt nhất, nhưng nó có thể được cải thiện bằng cách sử dụng tệp kiểu tệp từ Android để tùy chỉnh phông chữ của bạn cho tất cả các chế độ xem trong ứng dụng của bạn.

Mã của tôi ở đây


1

Có hai cách để tùy chỉnh phông chữ:

!!! phông chữ tùy chỉnh của tôi trong nội dung / phông chữ / iran_sans.ttf

Cách 1: Kiểu chữ chuyển hướng. Lớp | || cách tốt nhất

gọi FontsOverride.setDefaultFont () trong lớp mở rộng Ứng dụng, Mã này sẽ khiến tất cả các phông chữ phần mềm bị thay đổi, thậm chí là phông chữ Toasts

AppControll.java

public class AppController extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //Initial Font
        FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");

    }
}

Phông chữOverride.java

public class FontsOverride {

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

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

Cách 2: sử dụng setTypeface

để xem đặc biệt, chỉ cần gọi setTypeface () để thay đổi phông chữ.

CTextView.java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.java

public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}


0

Bạn có thể dễ dàng thực hiện lớp textview tùy chỉnh: -

Vì vậy, những gì bạn cần làm đầu tiên, làm cho Custom textviewlớp mở rộng với AppCompatTextView.

public class CustomTextView extends AppCompatTextView {
    private int mFont = FontUtils.FONTS_NORMAL;
    boolean fontApplied;

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

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

    public CustomTextView(Context context) {
        super(context);
        init(null, context);
    }

    protected void init(AttributeSet attrs, Context cxt) {
        if (!fontApplied) {
            if (attrs != null) {
                mFont = attrs.getAttributeIntValue(
                        "http://schemas.android.com/apk/res-auto", "Lato-Regular.ttf",
                        -1);
            }
            Typeface typeface = getTypeface();
            int typefaceStyle = Typeface.NORMAL;
            if (typeface != null) {
                typefaceStyle = typeface.getStyle();
            }
            if (mFont > FontUtils.FONTS) {
                typefaceStyle = mFont;
            }
            FontUtils.applyFont(this, typefaceStyle);
            fontApplied = true;
        }
    }
}

Bây giờ, mỗi khi cuộc gọi xem văn bản tùy chỉnh và chúng tôi sẽ nhận được giá trị int từ thuộc tính int fontValue = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto","Lato-Regular.ttf",-1).

Hoặc là

Chúng tôi cũng có thể nhận getTypeface () từ chế độ xem mà chúng tôi đặt trong xml ( android:textStyle="bold|normal|italic"). Vì vậy, làm những gì bạn muốn làm.

Bây giờ, chúng tôi thực hiện FontUtilsđể đặt bất kỳ phông chữ .ttf nào vào chế độ xem của chúng tôi.

public class FontUtils {

    public static final int FONTS = 1;
    public static final int FONTS_NORMAL = 2;
    public static final int FONTS_BOLD = 3;
    public static final int FONTS_BOLD1 = 4;

    private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();

    static Typeface getFonts(Context context, String name) {
        Typeface typeface = TYPEFACE.get(name);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(context.getAssets(), name);
            TYPEFACE.put(name, typeface);
        }
        return typeface;
    }

    public static void applyFont(TextView tv, int typefaceStyle) {

        Context cxt = tv.getContext();
        Typeface typeface;

        if(typefaceStyle == Typeface.BOLD_ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }else if (typefaceStyle == Typeface.BOLD || typefaceStyle == SD_FONTS_BOLD|| typefaceStyle == FONTS_BOLD1) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-SemiBold.ttf");
        } else if (typefaceStyle == Typeface.ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Thin.ttf");
        } else {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }
        if (typeface != null) {
            tv.setTypeface(typeface);
        }
    }
}

0

Có thể hữu ích khi biết rằng bắt đầu từ Android 8.0 (API cấp 26), bạn có thể sử dụng phông chữ tùy chỉnh trong XML .

Bạn có thể áp dụng một phông chữ tùy chỉnh cho toàn bộ ứng dụng theo cách sau.

  1. Đặt phông chữ trong thư mục res/font.

  2. Vào res/values/styles.xmlsử dụng nó trong các chủ đề ứng dụng. <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>



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.