เป็นไปได้ไหมที่จะตั้งค่าแบบอักษรที่กำหนดเองสำหรับแอพพลิเคชั่นทั้งหมด?


270

ฉันต้องใช้แบบอักษรบางอย่างสำหรับแอปพลิเคชันทั้งหมดของฉัน ฉันมีไฟล์. ttf เหมือนกัน เป็นไปได้ไหมที่จะตั้งค่านี้เป็นฟอนต์เริ่มต้นเมื่อเริ่มต้นแอปพลิเคชันแล้วใช้ที่อื่นในแอปพลิเคชันหรือไม่ เมื่อตั้งค่าฉันจะใช้งานใน XML เลย์เอาต์ของฉันได้อย่างไร


ใน android studio 3.0 คุณสามารถตั้งค่าฟอนต์ที่กำหนดเองได้อย่างง่ายดาย: developer.android.com/guide/topics/ui/look-and-feel/
......

@MHSFisher แบบอักษรใน XML เป็นคุณลักษณะสำหรับ Android 8.0 (API ระดับ 26)
Emi Raz

1
@EmiRaz โปรดอ่านเอกสารdeveloper.android.com/guide/topics/ui/look-and-feel/... ฟีเจอร์นี้เพิ่มเข้ามาใน
ไลบรารี่

คำตอบ:


449

ใช่พร้อมการสะท้อนกลับ งานนี้ ( ตามคำตอบนี้ ):

(หมายเหตุ: นี่เป็นวิธีแก้ปัญหาเนื่องจากไม่มีการสนับสนุนแบบอักษรที่กำหนดเองดังนั้นหากคุณต้องการเปลี่ยนสถานการณ์นี้โปรดทำเครื่องหมายดาวเพื่อโหวตปัญหา 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>

11
คุณจะเขียนทับตัวหนาและตัวเอียงในอวกาศได้อย่างไร
Christopher Rivera

2
@ChristopherRivera นอกจากนี้"DEFAULT_BOLD"ยังมีเขตข้อมูลส่วนตัว: private static Typeface[] sDefaults;คุณสามารถลองเข้าถึงสิ่งนี้โดยการไตร่ตรองและตั้งค่าsDefaults[Typeface.ITALIC]เป็น typeType ของคุณ ดูนี่สิ
weston

5
@weston ไม่เป็นไร ฉันทำได้สำเร็จ มีความเข้าใจผิดของฉัน คุณทำได้ดีมาก คุณบอกฉันได้ไหม ทำไมมันไม่ทำงานกับ DEFAULT Typeface? ฉันเปลี่ยน Typeface เป็น MONOSPACE ตามคำแนะนำของคุณแล้วใช้ loginc ก็ใช้งานได้ แต่ไม่ได้ทำงานกับ DEFAULT
Jay Pandya

2
ไม่สามารถพิมพ์ผิดแบบอักษรได้ แก้ไขโดยเพิ่มเส้นทางแบบอักษร "FontsOverride.setDefaultFont (นี่คือ" DEFAULT "," fonts / MyFontAsset.ttf ");"
Sai

3
ฉันคิดว่ามันน่ารำคาญจริงๆที่ต้องสลับค่าเริ่มต้นTextViewไปทุกที่เพื่อใช้แบบอักษรที่กำหนดเองหรือใช้วิธีแก้ปัญหาแบบสะท้อนกลับเช่นนี้ เมื่อรวมกับชุดแบบอักษรที่ จำกัด ที่มีอยู่ใน Android มันทำให้การพัฒนาแอพที่ดูดีเป็นงานที่หนักมาก ฉันได้เพิ่มคำขอคุณสมบัติไปยังตัวติดตามปัญหา Android หากคุณต้องการที่จะเห็นคุณลักษณะนี้คุณสามารถดาวปัญหาที่นี่: code.google.com/p/android/issues/...
แซม

64

มีห้องสมุดที่ยอดเยี่ยมสำหรับแบบอักษรที่กำหนดเองใน Android: การประดิษฐ์ตัวอักษร

นี่คือตัวอย่างวิธีการใช้งาน

ใน Gradle คุณต้องใส่บรรทัดนี้ลงในไฟล์ build.gradle ของแอปของคุณ:

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

จากนั้นสร้างคลาสที่ขยายApplicationและเขียนรหัสนี้:

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

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

และในคลาสกิจกรรมให้ใส่เมธอดนี้ก่อน onCreate:

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

และสิ่งสุดท้ายที่ไฟล์ Manifest ของคุณควรมีหน้าตาดังนี้:

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

และมันจะเปลี่ยนกิจกรรมทั้งหมดเป็นแบบอักษรของคุณ! มันง่ายและสะอาด!


1
นี่คือทางออกที่สมบูรณ์แบบ
nizam.sp

1
จริงมันเป็นโซลูชั่นที่สมบูรณ์แบบด้วยวิธีนี้ฉันไม่ต้องเขียนคลาสต่าง ๆ เพื่ออัปเดตแบบอักษรสำหรับรายการเมนูปุ่มตัวเลือกหรือช่องทำเครื่องหมาย fotns มันใช้ได้กับทุกคน !! ขอบคุณ :)
Manisha

2
ไม่ใช่โซลูชันที่สมบูรณ์แบบ: รูปแบบตัวหนา / ตัวเอียง / ตัวหนาตัวเอียงถูกเขียนทับ ขณะนี้ไม่มีวิธีง่าย ๆ ในการตั้งครอบครัวเหล่านั้น
0101100101

2
ถ้าฉันทำอย่างนั้นฉันจะเปลี่ยนจากตัวหนาเป็นปกติได้อย่างไร
GMX

2
เพื่อให้ได้ตัวหนาตัวเอียงหรือขีดเส้นใต้คุณลักษณะที่ผมเคยใช้<b></b>, <u></u>และ<i></i>ในstrings.xmlไฟล์และจนถึงขณะนี้ก็ทำงาน
jlively

47

แม้ว่าสิ่งนี้จะไม่สามารถใช้ได้กับแอปพลิเคชั่นทั้งหมด แต่มันก็ใช้ได้กับกิจกรรมและสามารถนำมาใช้ใหม่สำหรับกิจกรรมอื่นได้ ฉันได้อัปเดตรหัสของฉันด้วย @ FR073N เพื่อรองรับการดูอื่น ๆ ผมไม่แน่ใจว่าเกี่ยวกับปัญหาต่างๆButtons, RadioGroupsฯลฯ เพราะการเรียนเหล่านั้นขยายTextViewเพื่อให้พวกเขาควรจะทำงานได้ดี ฉันเพิ่มบูลีนแบบมีเงื่อนไขสำหรับการใช้การสะท้อนเนื่องจากดูเหมือนว่าแฮ็คมากและอาจลดประสิทธิภาพลงอย่างเห็นได้ชัด

หมายเหตุ: ตามที่ระบุไว้สิ่งนี้จะไม่ทำงานสำหรับเนื้อหาแบบไดนามิก! ด้วยเหตุนี้จึงเป็นไปได้ที่จะเรียกวิธีนี้ด้วยการพูดonCreateViewหรือgetViewวิธีการ แต่ต้องใช้ความพยายามเพิ่มเติม

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

    final int mCount = mContainer.getChildCount();

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

จากนั้นเพื่อใช้งานคุณจะทำสิ่งนี้:

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

หวังว่าจะช่วย


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

1
เป็นไปได้ ... แต่ตามข้อกำหนดของ Android ที่คุณต้องการหลีกเลี่ยงเลย์เอาต์ที่ลึกกว่า 4 ระดับและกว้าง 100 วิว (แม้จะค่อนข้างน้อย) การเรียกซ้ำอาจทำได้ไม่ดีในแง่ของประสิทธิภาพ แต่แม้ว่าเลย์เอาต์ของคุณจะมี 20 ระดับซึ่งไม่สำคัญนัก
Tom

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

1
แค่อยากจะเพิ่มโค้ดข้างต้นที่ครอบคลุม TextViews แต่ ListViews, Alerts, Toasts, Map Markers เป็นต้นจะยังคงใช้ฟอนต์ระบบ
csch

2
พวกฟังก์ชั่นนี้ใช้เวลา 3 พารามิเตอร์เมื่อคุณเรียกมันซ้ำคุณผ่าน 2 พารามิเตอร์ ??? อันไหนที่ถูกต้อง? สะท้อนคืออะไร?
MBH

34

สรุป:

ตัวเลือก # 1: ใช้การไตร่ตรองเพื่อใช้แบบอักษร (รวมคำตอบของWeston & Roger Huang ):

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

public final class FontsOverride { 

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

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

} 

การใช้งานในระดับแอปพลิเคชัน:

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

ตั้งค่าสไตล์เพื่อบังคับให้แอปพลิเคชันแบบอักษรแบบตัวกว้าง (ขึ้นอยู่กับlovefish ):

Pre-Lollipop:

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

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

Lollipop (API 21):

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

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

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

ตัวเลือกที่ 2: ซับคลาสแต่ละอันและทุกมุมมองที่คุณต้องการปรับแต่งแบบอักษรเช่น ListView, EditTextView, ปุ่มและอื่น ๆ ( คำตอบของPalani ):

public class CustomFontView extends TextView {

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

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

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

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

ตัวเลือกที่ 3: ใช้ตัวรวบรวมมุมมองที่สำรวจผ่านลำดับชั้นการดูของหน้าจอปัจจุบันของคุณ:

รูปแบบ # 1 ( คำตอบของTom ):

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

    final int mCount = mContainer.getChildCount();

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

การใช้งาน:

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

การเปลี่ยนแปลง # 2: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere

ตัวเลือก # 4: ใช้ 3 พรรค Lib เรียกว่าการเขียนพู่กัน

โดยส่วนตัวฉันขอแนะนำตัวเลือก # 4 เนื่องจากมันช่วยประหยัดอาการปวดหัวได้มาก


ในตัวเลือก # 1คุณหมายถึงอะไร"sans-serif"ในnewMap.put(และmonospaceในstyles! barana.ttfฉันต้องการใช้อักษรที่กำหนดเองที่มีชื่อว่า
Dr.jacky

ในตัวเลือก 1 ข้อมูลโค้ดแรกไม่สามารถทำงานกับ API ระดับ 22, Android 5.1.1 แต่ส่วนรหัสอื่น ๆ ไม่ สิ่งที่ควรจะแน่นอนหากมีเงื่อนไขเพื่อ?
user1510006

28

ฉันต้องการปรับปรุงคำตอบของwestonสำหรับ API 21 Android 5.0

สาเหตุ

ภายใต้ API 21 สไตล์ข้อความส่วนใหญ่รวมถึงการตั้งค่า fontFamily เช่น:

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

ซึ่งใช้แบบอักษรเริ่มต้นปกติของ Roboto:

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

คำตอบเดิมไม่สามารถใช้แบบอักษร monospace ได้เนื่องจาก android: fontFamily มีความสำคัญมากกว่าสำหรับ Android: แอตทริบิวต์ typeface ( อ้างอิง ) ใช้ Theme.Holo. * เป็นวิธีแก้ปัญหาที่ถูกต้องเนื่องจากไม่มี android: การตั้งค่า fontFamily ภายใน

สารละลาย

ตั้งแต่ Android 5.0 ใส่ตัวอักษรของระบบในตัวแปรแบบคงที่ Typeface.sSystemFontMap ( อ้างอิง ) เราสามารถใช้เทคนิคการสะท้อนเดียวกันเพื่อแทนที่:

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

4
วิธีแก้ปัญหาที่ดีสำหรับแอล แต่ฉันสงสัยว่าทำไมสิ่งนี้จึงไม่เหมาะกับButtonชื่อเรื่องและแถบเครื่องมือของฉัน ฉันเอาชนะแบบอักษรเริ่มต้นใน MainApplication FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");ดังนี้ ฉันใช้ Nexus 5, v5.1.1
kip2

3
เฮ้ขอบคุณสิ่งนี้มีประโยชน์มากเพียงสิ่งเดียว: สิ่งนี้ใช้ไม่ได้กับ Android 6 (API 22) จากนั้นควรเปลี่ยนรหัสเป็น: Build.VERSION.SDK_INT == 21- นั่นเป็นเพียงการAPI 21 ทดสอบ I ที่ Nexus กับ API 22
Saeid

ยังฉันไม่สามารถตั้งค่าแบบอักษรที่กำหนดเองโดยใช้วิธีนี้ใน Nexus 9
Rahul Upadhyay

2
ผู้ใดก็ตามที่มีปัญหาไม่ทำงานที่ 5.1+ อย่าเขียนทับแบบอักษรในสไตล์ values-v21 ของคุณ
มูฮัมหมัดบาบา

@MuhammadBabar ขอบคุณทางออกของคุณทำให้วันของฉัน
M.Yogeshwaran

15

มันง่ายมาก ... 1. ดาวน์โหลดและใส่ฟอนต์ที่กำหนดเองในสินทรัพย์ .. จากนั้นเขียนคลาสแยกต่างหากสำหรับการดูข้อความดังนี้: ที่นี่ฉันใช้ฟอนต์ฟอนต์

public class CusFntTextView extends TextView {

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

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

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

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

}

และทำสิ่งต่อไปนี้ใน xml:

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

ใช่มันใช้งานได้ :) แต่ถ้าฉันต้องการใช้แบบอักษรเดียวกันกับมุมมอง / วิดเจ็ตอื่น ๆ ที่เหลืออยู่ล่ะ? ฉันจำเป็นต้องเขียนคลาสแยกต่างหากสำหรับมุมมองอื่นทั้งหมด (รวมถึงไดอะล็อก / ขนมปังปิ้ง / แอ็คชั่นบาร์) ด้วยหรือไม่
Narendra Singh

ใช่สำหรับวิธีนี้คุณต้องเขียนคลาสแยกต่างหากสำหรับแต่ละมุมมองของคุณ
Saad Bilal

9

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

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

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

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

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

2
ระวังเมื่อทำสิ่งนี้บนแพลตฟอร์มก่อน 4.0 - สิ่งนี้จะรั่วไหลทรัพยากรจำนวนมากเนื่องจากข้อผิดพลาดใน Android: code.google.com/p/android/issues/detail?id=9904
Ryan M

เราจะเปลี่ยนกลับเป็นค่าเริ่มต้นได้อย่างไร ฉันกำลังทำสิ่งนี้: if (configShared.getString ("storeId", AppCredentials.DEFAULT_STORE_ID) .equals ("2")) {ฟิลด์สุดท้าย staticField = Typeface.class.getDeclaredFieldName (staticTypefaceFieldName); staticField.setAccessible (จริง); staticField.set (null, newTypeface); } else {StaticField ฟิลด์สุดท้าย = Typeface.class.getDeclaredField (staticTypefaceFieldName); staticField.setAccessible (จริง); staticField.set (null, null); }
นักฆ่า

8

ฉันต้องการที่จะปรับปรุงเวสตัน 's และโรเจอร์ Huang ' s คำตอบมานานกว่า 21 API Android อมยิ้มกับรูปแบบ ' Theme.AppCompat '

ด้านล่าง Android 4.4

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

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

API (สูงกว่า) เกิน 5.0

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

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

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

และไฟล์ util FontsOverrideก็เหมือนกับคำตอบของweston ฉันได้ทดสอบในโทรศัพท์เหล่านี้:

Nexus 5 (Android 5.1 ระบบ Android หลัก)

ZTE V5 (android 5.1 CM12.1)

XIAOMI note (android 4.4 MIUI6)

HUAWEI C8850 (android 2.3.5 UNKNOWN)


8

วิธีการแก้ปัญหาที่ยอดเยี่ยมสามารถพบได้ที่นี่: https://coderwall.com/p/qxxmaa/android-use-a-custom-font-everywhere

เพียงขยายกิจกรรมจาก BaseActivity และเขียนวิธีการเหล่านั้น นอกจากนี้คุณควรจะดีกว่าแบบอักษรแคชตามที่อธิบายไว้ที่นี่: https://stackoverflow.com/a/16902532/2914140


หลังจากการวิจัยบางอย่างฉันเขียนโค้ดที่ใช้งานได้กับ Samsung Galaxy Tab A (Android 5.0) รหัสมือสองของเวสตันและโรเจอร์ Huang เช่นเดียวกับhttps://stackoverflow.com/a/33236102/2914140 ทดสอบด้วย Lenovo TAB 2 A10-70L ด้วยซึ่งไม่สามารถใช้งานได้ ฉันแทรกตัวอักษร 'Comic Sans' ที่นี่เพื่อดูความแตกต่าง

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

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

    private Context context;

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

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

    private void overrideFonts(Map<String, Typeface> typefaces) {
        if (Build.VERSION.SDK_INT == 21) {
            try {
                final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
                field.setAccessible(true);
                Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
                if (oldFonts != null) {
                    oldFonts.putAll(typefaces);
                } else {
                    oldFonts = typefaces;
                }
                field.set(null, oldFonts);
                field.setAccessible(false);
            } catch (Exception e) {
                Log.e("TypefaceUtil", "Cannot set custom fonts");
            }
        } else {
            try {
                for (Map.Entry<String, Typeface> entry : typefaces.entrySet()) {
                    final Field staticField = Typeface.class.getDeclaredField(entry.getKey());
                    staticField.setAccessible(true);
                    staticField.set(null, entry.getValue());
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

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

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

    new FontsOverride(this).loadFonts();

สร้างโฟลเดอร์ 'แบบอักษร' ภายใน 'สินทรัพย์' และใส่แบบอักษรที่ต้องการที่นั่น การเรียนการสอนที่ง่ายอาจจะพบได้ที่นี่: https://stackoverflow.com/a/31697103/2914140

อุปกรณ์ Lenovo ยังได้รับค่าของแบบอักษรอย่างไม่ถูกต้อง ในครั้งส่วนใหญ่จะส่งกลับ Typeface.NORMAL บางครั้งก็เป็นโมฆะ แม้ว่า TextView จะเป็นตัวหนา (ในรูปแบบ xml-file) ดูที่นี่: TextView isBold ส่งคืน NORMALเสมอ วิธีนี้ข้อความบนหน้าจอจะเป็นแบบอักษรปกติไม่ใช่ตัวหนาหรือตัวเอียง ดังนั้นฉันคิดว่ามันเป็นข้อบกพร่องของผู้ผลิต


ฉันศึกษาซอร์สโค้ด Android คำตอบของคุณดีที่สุด มันสามารถแทนที่บางปานกลางแสงหรืออะไรก็ได้ ขอบคุณมาก!
โมฮัมหมัด Omidvar

6

ทำงานกับ Xamarin และ Android:

ประเภท:

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

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

การใช้งานแอปพลิเคชัน:

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

        }

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

        }

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

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

สไตล์:

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

6

ในฐานะที่เป็น Android O ตอนนี้เป็นไปได้ที่จะกำหนดโดยตรงจาก XML และข้อผิดพลาดของฉันตอนนี้ปิด!

ดูรายละเอียดที่นี่

TL; DR:

ก่อนอื่นคุณต้องเพิ่มแบบอักษรของคุณในโครงการ

ที่สองคุณเพิ่มตระกูลแบบอักษรเช่น:

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

สุดท้ายคุณสามารถใช้แบบอักษรในเลย์เอาต์หรือสไตล์:

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

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

สนุก!


ขอบคุณ เราควรใช้ Android Studio 2.4 เพื่อเพิ่มโฟลเดอร์ฟอนต์
โฟตอนพอยต์

ที่จริงฉันแค่ต้องใช้มันกับสไตล์ของฉันและมันจะถูกนำไปใช้ผ่านแอปพลิเคชัน แต่บางส่วน (การควบคุมที่เพิ่มโดยทางโปรแกรมจะต้องใช้ผ่านโค้ดจาวา)
SolidSnake

4

คุณสามารถตั้งค่าฟอนต์ที่กำหนดเองสำหรับทุกเลย์เอาท์ทีละคนด้วยการเรียกใช้ฟังก์ชั่นเพียงครั้งเดียวจากทุกเลย์เอาท์โดยผ่านรูทของ View.First สร้างแนวทาง Singelton สำหรับการเข้าถึงวัตถุฟอนต์เช่นนี้

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

    private Font() {

    }

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

    }

    public void init(Context context) {

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

}

คุณสามารถกำหนดแบบอักษรที่แตกต่างกันในระดับบนตอนนี้กำหนดระดับตัวอักษรตัวช่วยเหลือที่จะใช้แบบอักษร:

   public class FontHelper {

    private static Font font;

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

        font = Font.getInstance(context);

        apply((ViewGroup)parentView);

    }

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

            View view = parentView.getChildAt(i);

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

            if (view instanceof EditText) {

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

            }
            if (view instanceof TextView) {

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

            }

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

        }

    }

}

ในโค้ดด้านบนฉันใช้ฟอนต์กับ textView และ EditText เท่านั้นคุณสามารถใช้ฟอนต์กับอิลิเมนต์มุมมองอื่นเช่นเดียวกันคุณต้องส่งรหัสของกลุ่มมุมมองรูทของคุณไปยังวิธีฟอนต์ข้างต้น เช่นเลย์เอาต์ของคุณคือ:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/mainParent"
    tools:context="${relativePackage}.${activityClass}" >

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

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

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

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

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

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

</RelativeLayout>

ในเค้าโครงด้านบนรหัสผู้ปกครองหลักคือ "ผู้ปกครองหลัก" ตอนนี้ให้ใช้แบบอักษร

public class MainActivity extends BaseFragmentActivity {

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

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

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

ไชโย :)


ดี .. ไม่สร้างตัวอักษรเหมือนกันอีกต่อไปใช้เพียง 1 แบบอักษรสำหรับทุกฟิลด์ :)
Arfan Mirza

3

ฉันขอแนะนำให้ขยาย TextView และใช้ TextView แบบกำหนดเองของคุณภายในโครงร่าง XML ของคุณหรือทุกที่ที่คุณต้องการ TextView ใน TextView ที่กำหนดเองของคุณให้แทนที่setTypeface

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

2

โซลูชันของทอมใช้งานได้ดี แต่ใช้ได้กับ TextView และ EditText เท่านั้น

หากคุณต้องการครอบคลุมมุมมองส่วนใหญ่ (RadioGroup, TextView, ช่องทำเครื่องหมาย ... ) ฉันได้สร้างวิธีการดังนี้:

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

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

วิธีนี้จะกลับสไตล์ของชุดมุมมองใน XML (ตัวหนาตัวเอียง ... ) และนำไปใช้หากมีอยู่

สำหรับ ListView ฉันจะสร้างอะแดปเตอร์เสมอและฉันจะตั้งค่าแบบอักษรภายใน getView


2

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

public final class TypefaceAssigner {

public final Typeface DEFAULT;
public final Typeface DEFAULT_BOLD;

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

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

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

ตอนนี้ในแฟรกเมนต์ทั้งหมดใน onViewCreated หรือ onCreateView ในกิจกรรมทั้งหมดใน onCreate และในอะแด็ปเตอร์มุมมองทั้งหมดใน getView หรือ newView เพียงเรียกใช้:

typefaceAssigner.assignTypeface(view);

2

ใน api 26 ที่มี build.gradle 3.0.0 และสูงกว่าคุณสามารถสร้างไดเรกทอรีฟอนต์ใน res และใช้บรรทัดนี้ในสไตล์ของคุณ

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

สำหรับการเปลี่ยนแปลง build.gradle ใช้สิ่งนี้ในการพึ่งพา build.gradle ของคุณ

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

และวิธีแทรกแบบอักษรในโครงการ
azerafati

@azerafati คัดลอกแบบอักษรของคุณไปเป็น res / font
Mohammad Hosein Heidari

ใช่เลย ฉันได้รับแล้ว แต่itemเพียงอย่างเดียวไม่ได้ตั้งค่าแบบอักษรสำหรับทั้งแอป เบาะแสใด ๆ
azerafati

1

ในที่สุด Google ก็ตระหนักถึงความรุนแรงของปัญหานี้ (การใช้แบบอักษรที่กำหนดเองกับองค์ประกอบ UI) และพวกเขาได้คิดค้นวิธีการแก้ปัญหาที่สะอาด

ก่อนอื่นคุณต้องอัปเดตเพื่อรองรับไลบรารี 26+ (คุณอาจต้องอัปเดต gradle ของคุณ {4.0+}, android studio) จากนั้นคุณสามารถสร้างโฟลเดอร์ทรัพยากรใหม่ที่เรียกว่าแบบอักษร ในโฟลเดอร์นี้คุณสามารถใส่ทรัพยากรแบบอักษร (.tff, ... ) จากนั้นคุณต้องแทนที่แอพเริ่มต้นและบังคับให้ฟอนต์ที่คุณกำหนดไว้เอง :)

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

หมายเหตุ: ถ้าคุณต้องการสนับสนุนอุปกรณ์ที่มี API เก่ากว่า 16 คุณต้องใช้เนมสเปซแอพแทน android!


0

ฉันต้องการปรับปรุงคำตอบของ Weston สำหรับ API 21 Android 5.0

ฉันมีปัญหาเดียวกันกับ Samsung s5 ของฉันเมื่อใช้แบบอักษร DEFAULT (ด้วยแบบอักษรอื่น ๆ มันใช้งานได้ดี)

ฉันจัดการเพื่อให้มันทำงานได้โดยการตั้งค่าแบบอักษร ("sans" เป็นต้น) ในไฟล์ XML สำหรับแต่ละ Textview หรือปุ่ม

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

และใน MyApplication Class:

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

หวังว่ามันจะช่วย



0

การประดิษฐ์ตัวอักษรใช้งานได้ดี แต่ไม่เหมาะสำหรับฉันเนื่องจากมันไม่รองรับน้ำหนักที่แตกต่าง (ตัวหนาตัวเอียง ฯลฯ ) สำหรับตระกูลฟอนต์

ดังนั้นฉันจึงลองใช้Fontainซึ่งช่วยให้คุณกำหนดมุมมองที่กำหนดเองและใช้ตระกูลแบบอักษรที่กำหนดเองได้

ในการใช้ Fontain คุณควรเพิ่มสิ่งต่อไปนี้ในโมดูลแอปของคุณ build.gradle:

compile 'com.scopely:fontain:1.0.0'

จากนั้นแทนที่จะใช้ TextView ปกติคุณควรใช้ FontTextView

ตัวอย่างของ FontTextView พร้อมเนื้อหาตัวพิมพ์ใหญ่และตัวหนา:

 <com.scopely.fontain.views.FontTextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/black"
            android:textColor="@android:color/white"
            android:textSize="11dp"
            android:gravity="center"
            android:id="@+id/tv1"
            app:font_family="myCustomFont"
            app:caps_mode="characters"
            app:font_weight="BOLD"/>

0
package com.theeasylearn.demo.designdemo;
import android.content.Context;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView;

public class MyButton extends TextView {

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

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

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

    private void init() {

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

    }

}

ไม่ใช่ทางออกที่สมบูรณ์แบบ การใช้โซลูชันนี้จะต้องใช้วิธีแก้ไขปัญหาแบบกำหนดเองเพื่อเข้าถึง Android TextViews
blueware

0

สำหรับการเปลี่ยนตระกูลฟอนต์เริ่มต้นของ TextViews ให้แทนที่ textViewStyle ในธีมแอพของคุณ

สำหรับการใช้แบบอักษรที่กำหนดเองใน fontFamily ให้ใช้ทรัพยากรแบบอักษรที่อยู่ในห้องสมุดสนับสนุน

ฟีเจอร์นี้ถูกเพิ่มเข้ามาใน Android 26 แต่กลับไปเป็นเวอร์ชั่นเก่าผ่านทาง supportlib

https://developer.android.com/guide/topics/resources/font-resource.html https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html # ใช้สนับสนุน-lib


0

ตั้งแต่เปิดตัว Android Oreo และห้องสมุดสนับสนุน (26.0.0) คุณสามารถทำได้อย่างง่ายดาย อ้างถึงคำตอบนี้ในคำถามอื่น

โดยทั่วไปสไตล์สุดท้ายของคุณจะมีลักษณะเช่นนี้:

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


-15

ใช่เป็นไปได้ที่จะตั้งค่าแบบอักษรเป็นแอปพลิเคชันทั้งหมด

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

ในการทำสิ่งนี้เพียงแค่สร้างสินทรัพย์ / โฟลเดอร์ในรูทโปรเจ็กต์และวางฟอนต์ของคุณ (ใน TrueType หรือ TTF แบบฟอร์ม) ในเนื้อหา

ตัวอย่างเช่นคุณอาจสร้างสินทรัพย์ / แบบอักษร / และวางไฟล์ TTF ของคุณลงในนั้น

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

Typeface face=Typeface.createFromAsset(getAssets(), "fonts/HandmadeTypewriter.ttf");
tv.setTypeface(face);
}
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.