แบบอักษรที่กำหนดเองและเค้าโครง XML (Android)


174

ฉันพยายามกำหนดโครงร่าง GUI โดยใช้ไฟล์ XML ใน Android เท่าที่ฉันสามารถหาได้ไม่มีวิธีที่จะระบุว่าวิดเจ็ตของคุณควรใช้แบบอักษรที่กำหนดเอง (เช่นที่คุณวางไว้ในสินทรัพย์ / font /) ในไฟล์ XML และคุณสามารถใช้แบบอักษรที่ติดตั้งระบบเท่านั้น

ฉันรู้ว่าในโค้ด Java ฉันสามารถเปลี่ยนแบบอักษรของแต่ละวิดเจ็ตด้วยตนเองโดยใช้ ID ที่ไม่ซ้ำกัน อีกทางหนึ่งฉันสามารถวนซ้ำวิดเจ็ตทั้งหมดใน Java เพื่อทำการเปลี่ยนแปลงนี้ แต่อาจช้ามาก

ฉันมีตัวเลือกอื่น ๆ อีกบ้าง? มีวิธีใดที่ดีกว่าในการสร้างวิดเจ็ตที่มีรูปลักษณ์ที่กำหนดเองหรือไม่? ฉันไม่ต้องการเปลี่ยนแบบอักษรด้วยตนเองสำหรับวิดเจ็ตใหม่ทุกอันที่ฉันเพิ่มด้วยตนเอง


68
DrDefrost - โปรดยอมรับคำตอบคุณจะได้รับคำตอบเพิ่มเติมในเว็บไซต์นี้
SK9

1
ต่อไปนี้เป็นคำถามที่คล้ายกันอีกข้อหนึ่ง: stackoverflow.com/questions/9030204/…
Vins

อัปเดตเมื่อวันที่ 05/2017: "ไลบรารีการสนับสนุน 26.0 เบต้าให้การสนับสนุนคุณลักษณะแบบอักษรใน XML บนอุปกรณ์ที่ใช้ Android API เวอร์ชัน 14 และสูงกว่า" ดู: developer.android.com/preview/features/…
อัลเบิร์ตควอนเบรา

คำตอบ:


220

คุณสามารถขยาย TextView แบบอักษรที่กำหนดเองชุดตามที่ผมได้เรียนรู้ที่นี่

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: (ในความละเอียด / ค่า)

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

main.xml:

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

คุณจะใส่ "saxmono.ttf" ในโฟลเดอร์ทรัพย์สิน

อัพเดท 8/1/13

มีความกังวลเกี่ยวกับหน่วยความจำร้ายแรงกับวิธีนี้ ดูความคิดเห็นของ chedabobด้านล่าง


5
ดูดี แต่ฉันได้รับข้อผิดพลาดเมื่อฉันพยายามใช้ "TextViewPlus" ใน main.xml ฉันได้รับต่อไปนี้: - ข้อผิดพลาด: ข้อผิดพลาดในการแยกวิเคราะห์ XML: คำนำหน้าไม่ได้ผูกไว้ - คำนำหน้า "foo" สำหรับแอตทริบิวต์ "foo: customFont" ที่เกี่ยวข้องกับประเภทองค์ประกอบ "supportLibs.TextViewPlus" จะไม่ถูกผูกไว้
Majjoodi

79
สิ่งหนึ่งที่ควรทราบคือมันจะสร้างวัตถุ TypeFace นับสิบและกินหน่วยความจำ มีข้อผิดพลาดใน pre-4.0 Android ที่ไม่เพิ่ม TypeFaces ให้เหมาะสม สิ่งที่ง่ายที่สุดที่จะทำคือสร้างแคช TypeFace ด้วย HashMap สิ่งนี้ทำให้การใช้งานหน่วยความจำในแอพของฉันลดลงจาก 120+ mb เป็น 18mb code.google.com/p/android/issues/detail?id=9904
chedabob

7
@Majjoodi: มันมักจะเกิดขึ้นถ้าคุณลืมที่จะเพิ่ม namespace ที่ 2 ในเค้าโครงของคุณ:xmlns:foo="http://schemas.android.com/apk/res/com.example
Theo

11
สิ่งสำคัญมาก - ฉันแค่ต้องการเพิ่มคำแนะนำของ chedabob ความเครียดเป็นสองเท่า คุณจะมีหน่วยความจำรั่วไหลใน ICS ล่วงหน้า มีโซลูชั่นที่มีไม่กี่คนหนึ่งของพวกเขาอยู่ในลิงค์ที่ให้ไว้โดย chedabob อีกแห่งหนึ่งอยู่ที่นี่: stackoverflow.com/questions/8057010/listview-memory-leak ปีเตอร์ - โปรดอัปเดตคำตอบของคุณ - ยอดเยี่ยม แต่ยังไม่สมบูรณ์
มิคาล K

1
ฉันจะตั้งค่าแอตทริบิวต์ที่กำหนดเองนี้ใน styles.xml นอกเหนือจากแอตทริบิวต์ textview อื่น ๆ เช่นความกว้างและความสูงได้อย่างไร
loeschg

35

ฉัน 3 ปีสำหรับงานปาร์ตี้ :( อย่างไรก็ตามนี่อาจเป็นประโยชน์สำหรับคนที่อาจสะดุดเมื่อโพสต์นี้

ฉันได้เขียนไลบรารีที่แคช Typefaces และอนุญาตให้คุณระบุ typefaces ที่กำหนดเองได้จาก XML คุณสามารถค้นหาห้องสมุดได้ที่นี่ที่นี่

นี่คือลักษณะ XML ของคุณที่จะมีลักษณะเมื่อคุณใช้งาน

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

เฮ้ @ Ragunath-jawahar ฉันจะนำเข้าห้องสมุดสำหรับโครงการ gradle ได้อย่างไร ฉันลองcompile 'com.mobsandgeeks:android-typeface-textview:1.0'แต่ไม่ได้ผล
aimango

1
คุณจะต้องมี AAR เพื่อให้สามารถใช้งานได้ ยังไม่ได้มี คุณสามารถคัดลอกแหล่งที่มาและสร้างโครงการ Android Studio Library ได้ในตอนนี้
Ragunath Jawahar

2
แท็ก geekui ของคุณมาจากไหน
sefirosu

3
จากเนมสเปซที่ระบุในแท็กหลัก -xmlns:geekui="http://schemas.android.com/apk/res-auto"
Ragunath Jawahar

1
@MuhammedRefaat ใช่มันไม่ :)
Ragunath Jawahar

18

อาจช้าไปหน่อย แต่คุณต้องสร้างคลาสซิงเกิลตันที่ส่งคืนแบบอักษรที่กำหนดเองเพื่อหลีกเลี่ยงการรั่วไหลของหน่วยความจำ

คลาส 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 ที่กำหนดเอง:

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

}

โดย 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" /> 

โปรแกรม:

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

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

ดูเหมือนว่าจะทำงานในรันไทม์ แต่มันควรจะทำงานในดีไซเนอร์ด้วยหรือไม่?
แมกนัสโจฮันสัน

แน่ใจ คุณสามารถใช้เป็น xml @Magnus
Leonardo Cardoso

ฉันคิดว่าคุณเข้าใจผิดดูเหมือนจะไม่ทำงานในเวลาออกแบบ (ดูตัวอย่างดีไซเนอร์) (xml! = ผู้ออกแบบ) มันทำงานได้ดีที่ระบุในไฟล์โครงร่าง XML ที่คอมไพล์เป็นรันไทม์ อย่างไรก็ตามฉันใช้ส่วนขยายนี้github.com/danh32/Fontifyซึ่งทำงานได้ดีกว่ามากสำหรับความต้องการของฉัน (รองรับรูปแบบตัวอักษรหลายแบบปกติตัวหนา ฯลฯ รวมถึงชื่อแบบอักษรที่แตกต่างกันรวมถึงตัวควบคุมอื่น ๆ นอกเหนือจาก TextView)
แมกนัส Johansson

2
getTypeFace สร้างแบบอักษรใหม่สำหรับการโทรทุกครั้ง ... นี่เป็นการเอาชนะวัตถุประสงค์ของซิงเกิล ควรมีฟิลด์สแตติกที่ตั้งค่าในครั้งแรกที่มีการโทรและส่งคืนค่าของฟิลด์ในการโทรครั้งต่อไป
Steven Pena

1
@chiwai คุณพูดถูก! เกี่ยวกับคำถามแรกที่ไม่ต้องการ ประมาณวินาทีที่มันเป็นคำผิด
Leonardo Cardoso

13

คำถามเก่า แต่ฉันหวังว่าฉันจะอ่านคำตอบนี้ที่นี่ก่อนที่ฉันจะเริ่มค้นหาคำตอบที่ดี การประดิษฐ์ตัวอักษรขยายandroid:fontFamilyคุณสมบัติเพื่อเพิ่มการรองรับแบบอักษรที่กำหนดเองในโฟลเดอร์เนื้อหาของคุณเช่น:

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

สิ่งเดียวที่คุณต้องทำเพื่อเปิดใช้งานคือการแนบไปกับบริบทของกิจกรรมที่คุณใช้:

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

คุณยังสามารถระบุแอตทริบิวต์ที่กำหนดเองของคุณเองเพื่อแทนที่ android:fontFamily

มันยังใช้งานได้ในธีมรวมถึง AppTheme


8

ใช้DataBinding :

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

ใน XML:

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

ไฟล์ตัวอักษรต้องอยู่ใน assets/fonts/


7

หากคุณมีแบบอักษรเดียวที่คุณต้องการเพิ่มและต้องการให้โค้ดน้อยลงคุณสามารถสร้าง TextView เฉพาะสำหรับแบบอักษรเฉพาะของคุณ ดูรหัสด้านล่าง

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

ใน main.xml ตอนนี้คุณสามารถเพิ่ม textView ของคุณแบบนี้:

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

ทำสิ่งนี้กับ init () และช่วยตัวคุณเองให้โทรเข้า 3x
ericosg

@ericosg ฉันได้รับข้อผิดพลาดนี้เมื่อฉันใช้วิธีแก้ปัญหาของคุณ android.view.InflateException: บรรทัดไฟล์ XML แบบไบนารี # 9: ข้อผิดพลาดพองคลาส com.ascent.adwad.utils.CustomTextView
Sagar Devanga

@SagarDevanga ยากที่จะช่วยโดยไม่มีข้อมูลเพิ่มเติม อาจใช้เวลานานเท่าที่จะทำได้และตั้งคำถามใหม่
ericosg

7

วิธีที่ดีที่สุดที่จะทำมันจาก Android O ปล่อยตัวอย่างเป็นวิธีนี้
1. ) คลิกขวาที่ละเอียดโฟลเดอร์และไปที่ใหม่> ไดเรกทอรีทรัพยากร
หน้าต่างไดเรกทอรีทรัพยากรใหม่จะปรากฏขึ้น
2. ) ในรายการประเภททรัพยากรให้เลือกแบบอักษรแล้วคลิกตกลง
3. ) เพิ่มไฟล์แบบอักษรของคุณในโฟลเดอร์แบบอักษรโครงสร้างโฟลเดอร์ด้านล่างสร้าง R.font.dancing_script, R.font.la_la และ R.font.ba_ba
4. ) ดับเบิลคลิกที่ไฟล์ฟอนต์เพื่อดูตัวอย่างฟอนต์ของไฟล์ในเครื่องมือแก้ไข

ต่อไปเราจะต้องสร้างตระกูลตัวอักษร

1. ) คลิกขวาที่โฟลเดอร์ตัวอักษรและไปที่ใหม่> Font แฟ้มทรัพยากร หน้าต่างไฟล์ทรัพยากรใหม่จะปรากฏขึ้น
2. ) ใส่ชื่อไฟล์แล้วคลิกตกลง แบบอักษรทรัพยากร XML ใหม่จะเปิดขึ้นในตัวแก้ไข
3. ) แนบไฟล์แบบอักษรลักษณะและน้ำหนักแต่ละไฟล์ในองค์ประกอบแท็กแบบอักษร XML ต่อไปนี้แสดงการเพิ่มแอตทริบิวต์ที่เกี่ยวข้องกับแบบอักษรใน 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>

การเพิ่มแบบอักษรไปยัง TextView:

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

จากเอกสารประกอบ

การทำงานกับแบบอักษร

ขั้นตอนทั้งหมดถูกต้อง


1
คำตอบที่ดีที่สุด! ชื่อไฟล์แบบอักษรจะต้องเป็นตัวพิมพ์เล็ก
Dmitry

คุณยังสามารถสร้างสไตล์ที่กำหนดเองที่คุณใช้กับแอปพลิเคชันของคุณ (ภายใต้ไฟล์ AndroidManifest) และมันจะถูกกำหนดให้กับทุกมุมมอง ตัวอย่างเช่นแทนที่จะวางไว้ใน TextView เดียวเพราะจะไม่มีผลกับ Toolbar
goldenmaza

5

ขยายTextViewและกำหนดแอตทริบิวต์ที่กำหนดเองหรือเพียงใช้แอตทริบิวต์ android: tag เพื่อส่งผ่านสตริงของฟอนต์ที่คุณต้องการใช้ คุณจะต้องเลือกการประชุมและทำตามเช่นฉันจะใส่แบบอักษรทั้งหมดของฉันใน res / ทรัพย์สิน / แบบอักษร / โฟลเดอร์เพื่อเรียน TextView ของคุณรู้ที่จะหาพวกเขา จากนั้นใน Constructor ของคุณคุณเพียงแค่ตั้งค่าฟอนต์ด้วยตนเองหลังจากการโทรสุด


4

วิธีเดียวที่จะใช้แบบอักษรที่กำหนดเองคือผ่านซอร์สโค้ด

เพียงจำไว้ว่า Android ทำงานบนอุปกรณ์ที่มีทรัพยากรและแบบอักษรที่ จำกัด มากอาจต้องใช้ RAM ในปริมาณที่เหมาะสม ฟอนต์ Droid ในตัวทำขึ้นเป็นพิเศษและหากคุณสังเกตเห็นว่ามีตัวละครและเครื่องประดับมากมายขาดหายไป


"เพียงจำไว้ว่า Android ทำงานบนอุปกรณ์ที่มีทรัพยากร จำกัด มาก" -> สิ่งนี้กำลังน้อยลงเรื่อย ๆ โทรศัพท์ Quad Core? จริงๆ??
Sandy

9
ฉันจะทำมากกว่านี้เพื่อแสดงให้เห็นถึงการพิจารณาบริบทของคำตอบของ tareqHs ซึ่งจะแสดงความคิดเห็นของคุณในช่วง 2 ปีครึ่งที่ดี
SK9

ส่วนแรกของการตอบสนองของคุณอาจเป็นจริงเมื่อคุณเขียนคำตอบของคุณในปี 2010 ส่วนหลังเป็น superfluoys และนอกเหนือจากจุด: Droid ไม่ดีทิ้งโดย Google ในปี 2012 เพื่อ Roboto การขาดตัวเลือกในการพิมพ์ใน Android เป็นข้อบกพร่องไม่ใช่คุณสมบัติ iOS มีฟอนต์หลายตัวสำหรับนักพัฒนาตั้งแต่ปี 2551 ภายใต้อุปกรณ์ดั้งเดิมตามมาตรฐานในปัจจุบัน
cosmix

คำตอบนี้ไม่ถูกต้องอีกต่อไป
Martin Konecny

2

ฉันอาจมีคำตอบง่ายๆสำหรับคำถามโดยไม่ขยาย TextView และใช้โค้ดแบบยาว

รหัส:

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

วางไฟล์ฟอนต์ที่กำหนดเองในโฟลเดอร์ทรัพย์สินตามปกติแล้วลองทำสิ่งนี้ มันใช้งานได้สำหรับฉัน ฉันแค่ไม่เข้าใจว่าทำไม peter ได้ให้รหัสขนาดใหญ่สำหรับสิ่งที่ง่ายนี้หรือเขาได้ให้คำตอบของเขาในรุ่นเก่า


2

นอกจากนี้ยังสามารถกำหนดได้ใน xml โดยไม่ต้องสร้างคลาสที่กำหนดเอง

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>

บันทึกย่ออย่างรวดเร็วเพราะฉันลืมที่จะวางแบบอักษรเสมอว่าแบบอักษรนั้นต้องอยู่ภายในassetsและโฟลเดอร์นี้อยู่ในระดับเดียวกับที่resและsrcในกรณีของฉันassets/fonts/ionicons.ttf

อัปเดตรูปแบบรูทที่เพิ่มเนื่องจากวิธีนี้จำเป็นต้องxmlns:app="http://schemas.android.com/apk/res-auto"ใช้งาน

อัปเดต 2ลืมเกี่ยวกับห้องสมุดที่ฉันติดตั้งก่อนเรียกว่าการประดิษฐ์ตัวอักษร


สิ่งนี้ไม่ได้ผลสำหรับฉัน เมื่อฉันพยายามสร้างสิ่งนี้ฉันได้รับข้อความแสดงข้อผิดพลาด: ข้อผิดพลาด: (49, 5) ไม่พบทรัพยากรที่ตรงกับชื่อที่กำหนด: attr 'fontPath'
Stef

ลองเพิ่มxmlns:app="http://schemas.android.com/apk/res-auto"ในรูปแบบรูทตรวจสอบคำตอบที่อัปเดตแล้ว
norman784

ข้อผิดพลาดไม่ได้มาจากไฟล์ XML โครงร่าง แต่มาจากไฟล์สไตล์ XML ดูเหมือนว่าจะไม่ 'รู้' ว่า fontPath คืออะไร
Stef

ถูกต้องลืมว่าฉันมีห้องสมุดชื่อ Calligrapy
norman784

1

คำตอบของปีเตอร์เป็นคำตอบที่ดีที่สุด แต่สามารถปรับปรุงได้โดยใช้ styles.xml จาก Android เพื่อกำหนดแบบอักษรของคุณสำหรับทุก textviews ในแอปของคุณ

รหัสของฉันอยู่ที่นี่


1

มีสองวิธีในการปรับแต่งแบบอักษร:

!!! แบบอักษรที่กำหนดเองของฉันใน asset / fonts / iran_sans.ttf

วิธีที่ 1: การ แก้ไข Typeface.class ||| วิธีที่ดีที่สุด

โทร FontsOverride.setDefaultFont () ในชั้นเรียนขยายแอพลิเคชัน, รหัสนี้จะทำให้แบบอักษรซอฟต์แวร์ทั้งหมดจะมีการเปลี่ยนแปลงแม้กระทั่งแบบอักษร Toasts

AppController.java

public class AppController extends Application {

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

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

    }
}

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

วิธีที่ 2:ใช้ setTypeface

สำหรับมุมมองพิเศษเพียงโทร setTypeface () เพื่อเปลี่ยนแบบอักษร

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

ต่อไปนี้เป็นบทแนะนำที่แสดงวิธีตั้งค่าแบบอักษรที่กำหนดเองเช่น @peter ที่อธิบาย: http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

ก็ยังมีการพิจารณาการรั่วไหลของหน่วยความจำที่มีศักยภาพ Ala http://code.google.com/p/android/issues/detail?id=9904 นอกจากนี้ในบทช่วยสอนเป็นตัวอย่างสำหรับการตั้งค่าแบบอักษรที่กำหนดเองบนปุ่ม


0

คุณสามารถสร้างคลาส textview ที่กำหนดเองได้อย่างง่ายดาย: -

ดังนั้นสิ่งที่คุณต้องทำก่อนให้ระดับที่ยื่นออกไปด้วยCustom textviewAppCompatTextView

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

ตอนนี้ทุกครั้งที่มีการเรียกดูข้อความที่กำหนดเองและเราจะได้รับค่า int จากคุณลักษณะ int fontValue = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto","Lato-Regular.ttf",-1)จากแอตทริบิวต์

หรือ

นอกจากนี้เรายังสามารถรับ getTypeface () จากมุมมองที่เราตั้งไว้ใน xml ของเรา (android:textStyle="bold|normal|italic" ) ดังนั้นทำในสิ่งที่คุณต้องการจะทำ

ตอนนี้เราสร้างFontUtilsชุดตัวอักษร. ttf ใด ๆ ลงในมุมมองของเรา

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

มันอาจจะเป็นประโยชน์ที่จะรู้ว่าเริ่มต้นจาก Android 8.0 (API ระดับ 26) คุณสามารถใช้ตัวอักษรที่กำหนดเองในรูปแบบ XML

คุณสามารถใช้แบบอักษรที่กำหนดเองกับแอปพลิเคชันทั้งหมดด้วยวิธีต่อไปนี้

  1. res/fontใส่ตัวอักษรในโฟลเดอร์

  2. ในการres/values/styles.xmlใช้งานในธีมแอพพลิเคชั่น <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>



โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.