วิธีการเปลี่ยนแบบอักษรครอบครัวของ TextView ใน Android


739

ดังนั้นฉันต้องการเปลี่ยนandroid:fontFamilyใน Android แต่ฉันไม่เห็นแบบอักษรที่กำหนดไว้ล่วงหน้าใน Android ฉันจะเลือกหนึ่งในสิ่งที่กำหนดไว้ล่วงหน้าได้อย่างไร ฉันไม่ต้องการกำหนด TypeFace ของฉันเอง แต่สิ่งที่ฉันต้องการคือสิ่งที่แตกต่างจากที่แสดงตอนนี้

<TextView
    android:id="@+id/HeaderText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="52dp"
    android:gravity="center"
    android:text="CallerBlocker"
    android:textSize="40dp"
    android:fontFamily="Arial"
 />

ดูเหมือนว่าสิ่งที่ฉันทำที่นั่นจะไม่ได้ผลจริงๆ! BTW android:fontFamily="Arial"เป็นความพยายามที่โง่!


ตรวจสอบลิงค์นี้stackoverflow.com/questions/2376250/…
duggu

คำตอบ:


1660

จาก android 4.1 / 4.2 / 5.0 สามารถใช้ตระกูลฟอนต์Robotoต่อไปนี้ได้:

android:fontFamily="sans-serif"           // roboto regular
android:fontFamily="sans-serif-light"     // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-black"     // roboto black
android:fontFamily="sans-serif-thin"      // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium"    // roboto medium (android 5.0)

ป้อนคำอธิบายรูปภาพที่นี่

ร่วมกับ

android:textStyle="normal|bold|italic"

16 ตัวแปรนี้เป็นไปได้:

  • Roboto ปกติ
  • Roboto ตัวเอียง
  • ตัวหนา Roboto
  • ตัวหนา Roboto
  • Roboto แสง
  • Roboto-Light ตัวเอียง
  • Roboto บาง
  • ตัวเอียง Roboto-Thin
  • Roboto-ย่อ
  • ตัวเอียง Roboto แบบย่อ
  • ตัวหนา Roboto- ข้น
  • ตัวหนาแบบโรโบโตควบแน่น
  • Roboto ดำ
  • ตัวเอียง Roboto-Black
  • Roboto กลางและขนาดย่อม
  • ตัวเอียง Roboto-Medium

fonts.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="font_family_light">sans-serif-light</string>
    <string name="font_family_medium">sans-serif-medium</string>
    <string name="font_family_regular">sans-serif</string>
    <string name="font_family_condensed">sans-serif-condensed</string>
    <string name="font_family_black">sans-serif-black</string>
    <string name="font_family_thin">sans-serif-thin</string>
</resources>

17
อย่าลืมสิ่งนี้: android: fontFamily = "sans-serif-thin" // roboto thin
Sam Lu

6
ฉันเห็นตัวแปรที่เรียกว่า "ตัวพิมพ์เล็กดำ" ในหนังสือตัวอย่าง robotoแต่ฉันไม่สามารถใช้งานได้ การใช้android:fontFamily="sans-serif-black-small-caps"ไม่ทำงาน มีใครรู้บ้าง
tbruyelle

3
ฉันไม่สามารถค้นหาแบบอักษรตระกูลใด ๆ ที่คุณพิมพ์ที่นี่ฉันไม่สามารถค้นหา "sans-serif" ด้วยกันได้
มอนตี้

9
นี่คือรายการที่ดี ใครบ้างมีลิงค์ไปยังที่ข้อมูลนี้มาจากไหน? มันจะดีถ้า Google มีสิ่งนี้ในเอกสารของพวกเขาในสถานที่หาง่ายพูดสำหรับเอกสารของandroid:fontFamilyใน TextView
Christopher Perry

8
รายการแบบอักษรที่ชัดเจนสามารถพบได้ในsystem_fonts.xmlตามที่อธิบายไว้ที่นี่
Newtonx

207

นี่คือวิธีการตั้งค่าแบบอักษรโดยทางโปรแกรม:

TextView tv = (TextView) findViewById(R.id.appname);
Typeface face = Typeface.createFromAsset(getAssets(),
            "fonts/epimodem.ttf");
tv.setTypeface(face);

วางไฟล์ฟอนต์ในโฟลเดอร์ทรัพย์สินของคุณ ในกรณีของฉันฉันสร้างไดเรกทอรีย่อยที่เรียกว่าแบบอักษร

แก้ไข:หากคุณสงสัยว่าโฟลเดอร์สินทรัพย์ของคุณอยู่ที่ไหนดูคำถามนี้


34
ขณะนี้ไม่ทำงานโปรดทราบว่านี้สามารถสร้างหน่วยความจำรั่ว สามารถแก้ไขได้โดยใช้คำตอบนี้
Charles Madere

@ScootrNova ฉันได้รับข้อผิดพลาดนี้เมื่อฉันใช้โซลูชันของคุณ ข้อผิดพลาด: ไม่พบเนื้อหาแบบอักษร gothic.ttf
Sagar Devanga

วิธีนี้จะใช้กับแอพทั้งหมดหรือไม่ ตอนนี้ในตัวอย่างคุณกำลังใช้กับข้อความเท่านั้น
Pritish Joshi

176

เริ่มจากAndroid-Studio 3.0 มันง่ายมากที่จะเปลี่ยนตระกูลแบบอักษร

ใช้ไลบรารีการสนับสนุน 26 มันจะทำงานบนอุปกรณ์ที่ใช้ Android API เวอร์ชัน 16 ขึ้นไป

สร้างโฟลเดอร์fontภายใต้resไดเรกทอรีดาวน์โหลดแบบอักษรที่คุณต้องการและวางไว้ในfontโฟลเดอร์ โครงสร้างควรมีลักษณะดังนี้

ที่นี่

หมายเหตุ:ในฐานะที่เป็นห้องสมุดสนับสนุน Android 26.0 คุณจะต้องประกาศคุณสมบัติทั้งสองชุด (android: และแอพ:) เพื่อให้แน่ใจว่าแบบอักษรของคุณโหลดบนอุปกรณ์ที่ใช้ Api 26 หรือต่ำกว่า

ตอนนี้คุณสามารถเปลี่ยนแบบอักษรโดยใช้เค้าโครง

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

ในการเปลี่ยนแปลงโดยทางโปรแกรม

 Typeface typeface = getResources().getFont(R.font.myfont);
   //or to support all versions use
Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
 textView.setTypeface(typeface);  

ในการเปลี่ยนแบบอักษรโดยใช้styles.xml ให้สร้างสไตล์

 <style name="Regular">
        <item name="android:fontFamily">@font/dancing_script</item>
        <item name="fontFamily">@font/dancing_script</item>
        <item name="android:textStyle">normal</item>
 </style>

และใช้สไตล์นี้กับ TextView

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    style="@style/Regular"/>

คุณยังสามารถสร้างตระกูลแบบอักษรของคุณเอง

-คลิกขวาที่โฟลเดอร์ตัวอักษรและไปที่ใหม่> Font แฟ้มทรัพยากร หน้าต่างไฟล์ทรัพยากรใหม่จะปรากฏขึ้น

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

ตัวอย่างเช่นเขียนตระกูลแบบอักษรของคุณเองที่นี่

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

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

1.ในการเปลี่ยนแบบอักษรครอบครัวในเลย์เอาต์คุณสามารถเขียน

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

2.การเปลี่ยนโปรแกรม

 Typeface typeface = getResources().getFont(R.font.lobster);
   //or to support all versions use
Typeface typeface = ResourcesCompat.getFont(context, R.font.lobster);
 textView.setTypeface(typeface);  

หากต้องการเปลี่ยนแบบอักษรของทั้งแอปให้เพิ่มสองบรรทัดเหล่านี้ใน AppTheme

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

ดูเอกสารประกอบการสอนแบบอักษร Android ที่กำหนดเองสำหรับข้อมูลเพิ่มเติม


7
หมายเหตุ: ขณะนี้สามารถใช้งานได้ใน Android Studio 3.0 Preview เท่านั้น มันไม่ได้ผลสำหรับฉันใน Android Studio 2.3.3 หวังว่าจะช่วยให้ใครบางคนในเวลา!
Tash Pemhiwa

2
คุณจะได้รับแบบอักษรจากภายในส่วนอย่างไรเนื่องจากคุณทำgetResources()ไม่ได้? แก้ไข : บรรทัดนี้ในตอนท้ายของคำตอบของคุณทำงานให้ฉัน: Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
Paradox

อย่างใดมันทำให้ตัวอักษรดูเสียหายในกรณีของฉันเมื่อเทียบกับ Caligtraphy fontWeight ไม่ได้ทำอะไรเลย
Leo Droidcoder

@LeoDroidcoder ใช้งานได้ตรวจสอบให้แน่ใจว่าคุณใช้ทั้งคู่android:fontWeightและapp:fontWeight
Manohar Reddy

ฉันตรวจสอบหลายครั้ง ไม่มีผลกระทบ
Leo Droidcoder

100

ฉันต้องแยกวิเคราะห์/system/etc/fonts.xmlในโครงการล่าสุด นี่คือตระกูลแบบอักษรปัจจุบันของ Lollipop:

╔════╦════════════════════════════╦═════════════════════════════╗
     FONT FAMILY                 TTF FILE                    
╠════╬════════════════════════════╬═════════════════════════════╣
  1  casual                      ComingSoon.ttf              
  2  cursive                     DancingScript-Regular.ttf   
  3  monospace                   DroidSansMono.ttf           
  4  sans-serif                  Roboto-Regular.ttf          
  5  sans-serif-black            Roboto-Black.ttf            
  6  sans-serif-condensed        RobotoCondensed-Regular.ttf 
  7  sans-serif-condensed-light  RobotoCondensed-Light.ttf   
  8  sans-serif-light            Roboto-Light.ttf            
  9  sans-serif-medium           Roboto-Medium.ttf           
 10  sans-serif-smallcaps        CarroisGothicSC-Regular.ttf 
 11  sans-serif-thin             Roboto-Thin.ttf             
 12  serif                       NotoSerif-Regular.ttf       
 13  serif-monospace             CutiveMono.ttf              
╚════╩════════════════════════════╩═════════════════════════════╝

นี่คือ parser (จากFontListParser ):

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

/**
 * Helper class to get the current font families on an Android device.</p>
 * 
 * Usage:</p> {@code List<SystemFont> fonts = FontListParser.safelyGetSystemFonts();}</p>
 */
public final class FontListParser {

    private static final File FONTS_XML = new File("/system/etc/fonts.xml");

    private static final File SYSTEM_FONTS_XML = new File("/system/etc/system_fonts.xml");

    public static List<SystemFont> getSystemFonts() throws Exception {
        String fontsXml;
        if (FONTS_XML.exists()) {
            fontsXml = FONTS_XML.getAbsolutePath();
        } else if (SYSTEM_FONTS_XML.exists()) {
            fontsXml = SYSTEM_FONTS_XML.getAbsolutePath();
        } else {
            throw new RuntimeException("fonts.xml does not exist on this system");
        }
        Config parser = parse(new FileInputStream(fontsXml));
        List<SystemFont> fonts = new ArrayList<>();

        for (Family family : parser.families) {
            if (family.name != null) {
                Font font = null;
                for (Font f : family.fonts) {
                    font = f;
                    if (f.weight == 400) {
                        break;
                    }
                }
                SystemFont systemFont = new SystemFont(family.name, font.fontName);
                if (fonts.contains(systemFont)) {
                    continue;
                }
                fonts.add(new SystemFont(family.name, font.fontName));
            }
        }

        for (Alias alias : parser.aliases) {
            if (alias.name == null || alias.toName == null || alias.weight == 0) {
                continue;
            }
            for (Family family : parser.families) {
                if (family.name == null || !family.name.equals(alias.toName)) {
                    continue;
                }
                for (Font font : family.fonts) {
                    if (font.weight == alias.weight) {
                        fonts.add(new SystemFont(alias.name, font.fontName));
                        break;
                    }
                }
            }
        }

        if (fonts.isEmpty()) {
            throw new Exception("No system fonts found.");
        }

        Collections.sort(fonts, new Comparator<SystemFont>() {

            @Override
            public int compare(SystemFont font1, SystemFont font2) {
                return font1.name.compareToIgnoreCase(font2.name);
            }

        });

        return fonts;
    }

    public static List<SystemFont> safelyGetSystemFonts() {
        try {
            return getSystemFonts();
        } catch (Exception e) {
            String[][] defaultSystemFonts = {
                    {
                            "cursive", "DancingScript-Regular.ttf"
                    }, {
                            "monospace", "DroidSansMono.ttf"
                    }, {
                            "sans-serif", "Roboto-Regular.ttf"
                    }, {
                            "sans-serif-light", "Roboto-Light.ttf"
                    }, {
                            "sans-serif-medium", "Roboto-Medium.ttf"
                    }, {
                            "sans-serif-black", "Roboto-Black.ttf"
                    }, {
                            "sans-serif-condensed", "RobotoCondensed-Regular.ttf"
                    }, {
                            "sans-serif-thin", "Roboto-Thin.ttf"
                    }, {
                            "serif", "NotoSerif-Regular.ttf"
                    }
            };
            List<SystemFont> fonts = new ArrayList<>();
            for (String[] names : defaultSystemFonts) {
                File file = new File("/system/fonts", names[1]);
                if (file.exists()) {
                    fonts.add(new SystemFont(names[0], file.getAbsolutePath()));
                }
            }
            return fonts;
        }
    }

    /* Parse fallback list (no names) */
    public static Config parse(InputStream in) throws XmlPullParserException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(in, null);
            parser.nextTag();
            return readFamilies(parser);
        } finally {
            in.close();
        }
    }

    private static Alias readAlias(XmlPullParser parser) throws XmlPullParserException, IOException {
        Alias alias = new Alias();
        alias.name = parser.getAttributeValue(null, "name");
        alias.toName = parser.getAttributeValue(null, "to");
        String weightStr = parser.getAttributeValue(null, "weight");
        if (weightStr == null) {
            alias.weight = 0;
        } else {
            alias.weight = Integer.parseInt(weightStr);
        }
        skip(parser); // alias tag is empty, ignore any contents and consume end tag
        return alias;
    }

    private static Config readFamilies(XmlPullParser parser) throws XmlPullParserException,
            IOException {
        Config config = new Config();
        parser.require(XmlPullParser.START_TAG, null, "familyset");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            if (parser.getName().equals("family")) {
                config.families.add(readFamily(parser));
            } else if (parser.getName().equals("alias")) {
                config.aliases.add(readAlias(parser));
            } else {
                skip(parser);
            }
        }
        return config;
    }

    private static Family readFamily(XmlPullParser parser) throws XmlPullParserException,
            IOException {
        String name = parser.getAttributeValue(null, "name");
        String lang = parser.getAttributeValue(null, "lang");
        String variant = parser.getAttributeValue(null, "variant");
        List<Font> fonts = new ArrayList<Font>();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String tag = parser.getName();
            if (tag.equals("font")) {
                String weightStr = parser.getAttributeValue(null, "weight");
                int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
                boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
                String filename = parser.nextText();
                String fullFilename = "/system/fonts/" + filename;
                fonts.add(new Font(fullFilename, weight, isItalic));
            } else {
                skip(parser);
            }
        }
        return new Family(name, fonts, lang, variant);
    }

    private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        int depth = 1;
        while (depth > 0) {
            switch (parser.next()) {
            case XmlPullParser.START_TAG:
                depth++;
                break;
            case XmlPullParser.END_TAG:
                depth--;
                break;
            }
        }
    }

    private FontListParser() {

    }

    public static class Alias {

        public String name;

        public String toName;

        public int weight;
    }

    public static class Config {

        public List<Alias> aliases;

        public List<Family> families;

        Config() {
            families = new ArrayList<Family>();
            aliases = new ArrayList<Alias>();
        }

    }

    public static class Family {

        public List<Font> fonts;

        public String lang;

        public String name;

        public String variant;

        public Family(String name, List<Font> fonts, String lang, String variant) {
            this.name = name;
            this.fonts = fonts;
            this.lang = lang;
            this.variant = variant;
        }

    }

    public static class Font {

        public String fontName;

        public boolean isItalic;

        public int weight;

        Font(String fontName, int weight, boolean isItalic) {
            this.fontName = fontName;
            this.weight = weight;
            this.isItalic = isItalic;
        }

    }

    public static class SystemFont {

        public String name;

        public String path;

        public SystemFont(String name, String path) {
            this.name = name;
            this.path = path;
        }

    }
}

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

ตัวอย่างเล็ก ๆ ที่ไม่สมบูรณ์:

final List<FontListParser.SystemFont> fonts = FontListParser.safelyGetSystemFonts();
String[] items = new String[fonts.size()];
for (int i = 0; i < fonts.size(); i++) {
    items[i] = fonts.get(i).name;
}

new AlertDialog.Builder(this).setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        FontListParser.SystemFont selectedFont = fonts.get(which);
        // TODO: do something with the font
        Toast.makeText(getApplicationContext(), selectedFont.path, Toast.LENGTH_LONG).show();
    }
}).show();

คุณรู้หรือไม่ว่ารุ่นของ Android ที่เพิ่มแบบอักษรใด
นักพัฒนา android

@androiddeveloper ฉันทำไม่ได้ คุณสามารถค้นหาโดยดูการเปลี่ยนแปลงที่นี่: github.com/android/platform_frameworks_base/blob/ ......
Jared Rummler

@ JaredRummler ให้อภัยความไม่รู้ของฉัน ทำไมน้ำหนัก == 400 คืออะไร?
ซามูเอล

1
@ ซามูเอลฉันไม่ได้ดูรหัสนี้มานานแล้ว แต่ตัวอักษร 400 น้ำหนักใช้สำหรับแบบอักษร "ปกติ" หรือ "ปกติ" ตัวอย่าง Roboto-Regular มีน้ำหนัก 400
Jared Rummler

สิ่งนี้ต้องการรูตหรือบางสิ่งหรือไม่? ฉันรันรหัสนี้บนเครื่องจำลอง Android (รุ่น 8.1) และเมื่อฉันโทรgetSystemFonts()ฉันได้รับการยกเว้นorg.xmlpull.v1.XmlPullParserException: END_TAG expected (position:START_TAG (empty) <axis tag='wdth' stylevalue='100.0'>@219:51 in java.io.InputStreamReader@f001fb3)
Damn Vegetables

49

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

TextView textView = (TextView) findViewById(<your TextView ID>);
Typeface typeFace = Typeface.createFromAsset(getAssets(), "<file name>");
textView.setTypeface(typeFace);

โปรดทราบว่าคุณสามารถเรียกใช้รหัสนี้หลังจาก setContentView () ถูกเรียกแล้ว นอกจากนี้ Android รองรับฟอนต์บางตัวเท่านั้นและควรอยู่ในรูปแบบ.ttf (TrueType)หรือ .otf (OpenType)ถึงตอนนั้นแบบอักษรบางตัวอาจใช้งานไม่ได้

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

การอัปเดต Android O: ตอนนี้สามารถทำได้ด้วยXML ใน Android Oตามความคิดเห็นของโรเจอร์


"Android ไม่อนุญาตให้คุณตั้งค่าแบบอักษรที่กำหนดเองจากเค้าโครง XML" สิ่งนี้มีการเปลี่ยนแปลงใน Android O ซึ่งช่วยให้คุณสร้างตระกูลฟอนต์ที่กำหนดเองและนำไปใช้ใน XML: developer.android.com/preview/features/working-with-fonts.html
Roger Huang


25

android:typefaceมันเป็นเช่นเดียวกับ

แบบอักษรในตัวคือ:

  • ปกติ
  • ซอง
  • serif
  • monospace

ดูหุ่นยนต์: อักษร


4
ฉันไม่คิดว่ามันเป็นสิ่งเดียวกัน แต่ดูเหมือนว่าเราไม่สามารถใช้ทั้งคู่ได้ ดูเหมือนว่าขณะนี้มีแอตทริบิวต์ที่แตกต่างกันไม่น้อยกว่าสามรายการที่แมปsetTypeface()ไว้ กล่าวคือfontFamily, และtypeface textStyleแต่ฉันไม่สามารถใช้ชีวิตของฉันเพื่อค้นหาว่าสิ่งเหล่านี้รวมกันอย่างแม่นยำเพื่อแก้ไขอินสแตนซ์ของแบบอักษรที่เป็นรูปธรรมได้อย่างไร มีใครคิดออกหรือไม่ เอกสารของ Google มีประโยชน์น้อยกว่า ...
Rad Haring

23

หากคุณต้องการโปรแกรมคุณสามารถใช้

label.setTypeface(Typeface.SANS_SERIF, Typeface.ITALIC);

ในกรณีที่SANS_SERIFคุณสามารถใช้:

  • DEFAULT
  • DEFAULT_BOLD
  • MONOSPACE
  • SANS_SERIF
  • SERIF

และสถานที่ที่ITALICคุณสามารถใช้:

  • BOLD
  • BOLD_ITALIC
  • ITALIC
  • NORMAL

ทั้งหมดระบุไว้ในผู้พัฒนา Android


15

ฉันใช้การประดิษฐ์ตัวอักษรในห้องสมุดที่ยอดเยี่ยมโดย Chris Jenx ออกแบบมาเพื่อให้คุณใช้แบบอักษรที่กำหนดเองในแอปพลิเคชัน Android ของคุณ ให้มันลอง!


ครับ แต่สำหรับตัวอย่างเช่นผมต้องการที่จะใช้ functionanl แต่ didn ทีต้องการที่จะใช้ห้องสมุดทั้งหมด;)
ซอฟ

12

สิ่งที่คุณต้องการเป็นไปไม่ได้ คุณต้องตั้งTypeFaceรหัสของคุณ

ในXMLสิ่งที่คุณสามารถทำได้คือ

android:typeface="sans" | "serif" | "monospace"

นอกเหนือจากนี้คุณไม่สามารถเล่นมากด้วยแบบอักษรใน XML :)

สำหรับArialคุณจะต้องตั้งใบหน้าชนิดในรหัสของคุณ


11

วิธีง่ายๆในการจัดการแบบอักษรคือการประกาศผ่านทางแหล่งข้อมูลเช่น:

<!--++++++++++++++++++++++++++-->
<!--added on API 16 (JB - 4.1)-->
<!--++++++++++++++++++++++++++-->
<!--the default font-->
<string name="fontFamily__roboto_regular">sans-serif</string>
<string name="fontFamily__roboto_light">sans-serif-light</string>
<string name="fontFamily__roboto_condensed">sans-serif-condensed</string>

<!--+++++++++++++++++++++++++++++-->
<!--added on API 17 (JBMR1 - 4.2)-->
<!--+++++++++++++++++++++++++++++-->
<string name="fontFamily__roboto_thin">sans-serif-thin</string>

<!--+++++++++++++++++++++++++++-->
<!--added on Lollipop (LL- 5.0)-->
<!--+++++++++++++++++++++++++++-->
<string name="fontFamily__roboto_medium">sans-serif-medium</string>
<string name="fontFamily__roboto_black">sans-serif-black</string>
<string name="fontFamily__roboto_condensed_light">sans-serif-condensed-light</string>

สิ่งนี้ขึ้นอยู่กับซอร์สโค้ดที่นี่และที่นี่


จะประกาศที่ไหน
AZ_

@AZ_ เช่นเดียวกับไฟล์ทรัพยากรจำนวนมากคุณสามารถวางไว้ในไฟล์ XML ใด ๆ ที่คุณต้องการในโฟลเดอร์ "res / values ​​/" ตัวอย่างเช่นวางไว้ใน "res / values ​​/ fonts.xml" และเพื่อที่จะใช้ทำเช่นนี้เช่น: android: fontFamily = "string / fontFamily__roboto_regular"
นักพัฒนา Android

ขอบคุณฉันใช้github.com/norbsoft/android-typeface-helperนี้และเป็นประโยชน์จริง ๆ
AZ_

โอเคห้องสมุดน่าจะใช้โปรแกรมได้ ที่นี่มีไว้สำหรับ XML
นักพัฒนา android

9

แบบไดนามิกคุณสามารถตั้งค่า fontfamily คล้ายกับ android: fontFamily ใน xml โดยใช้สิ่งนี้

For Custom font:

 TextView tv = ((TextView) v.findViewById(R.id.select_item_title));
 Typeface face=Typeface.createFromAsset(getAssets(),"fonts/mycustomfont.ttf"); 
 tv.setTypeface(face);

For Default font:

 tv.setTypeface(Typeface.create("sans-serif-medium",Typeface.NORMAL));

นี่คือรายการของตระกูลฟอนต์เริ่มต้นที่ใช้ใช้สิ่งนี้โดยแทนที่สตริงอัญประกาศคู่"sans-serif-medium"

FONT FAMILY                    TTF FILE                    

1  casual                      ComingSoon.ttf              
2  cursive                     DancingScript-Regular.ttf   
3  monospace                   DroidSansMono.ttf           
4  sans-serif                  Roboto-Regular.ttf          
5  sans-serif-black            Roboto-Black.ttf            
6  sans-serif-condensed        RobotoCondensed-Regular.ttf 
7  sans-serif-condensed-light  RobotoCondensed-Light.ttf   
8  sans-serif-light            Roboto-Light.ttf            
9  sans-serif-medium           Roboto-Medium.ttf           
10  sans-serif-smallcaps       CarroisGothicSC-Regular.ttf 
11  sans-serif-thin            Roboto-Thin.ttf             
12  serif                      NotoSerif-Regular.ttf       
13  serif-monospace            CutiveMono.ttf              

"mycustomfont.ttf" เป็นไฟล์ ttf เส้นทางจะอยู่ในsrc / assets / fonts / mycustomfont.ttfคุณสามารถอ้างอิงเพิ่มเติมเกี่ยวกับแบบอักษรเริ่มต้นในตระกูลแบบอักษรเริ่มต้นนี้


9
Typeface typeface = ResourcesCompat.getFont(context, R.font.font_name);
textView.setTypeface(typeface);

ตั้งค่าฟอนต์ให้เป็น textview ได้อย่างง่ายดายจาก res> font directory โดยทางโปรแกรม


8

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

textView.setTypeface(ResourcesCompat.getFont(this, R.font.lato));

6

ด้วยการลองผิดลองถูกฉันได้เรียนรู้สิ่งต่อไปนี้

ภายใน * .xml คุณสามารถรวมแบบอักษรหุ้นกับฟังก์ชั่นต่อไปนี้ไม่เพียง แต่กับแบบอักษร:

 android:fontFamily="serif" 
 android:textStyle="italic"

ด้วยสองสไตล์นี้ไม่จำเป็นต้องใช้แบบอักษรในกรณีอื่นใด ช่วงของชุดค่าผสมมีขนาดใหญ่กว่ามากขึ้นด้วย fontfamily & textStyle


5

ค่าที่ถูกต้องของ android: fontFamily ถูกกำหนดใน /system/etc/system_fonts.xml(4.x) หรือ /system/etc/fonts.xml(5.x) แต่ผู้ผลิตอุปกรณ์อาจแก้ไขได้ดังนั้นแบบอักษรจริงที่ใช้โดยการตั้งค่า fontFamily ขึ้นอยู่กับไฟล์ที่กล่าวถึงข้างต้นของอุปกรณ์ที่ระบุ

ใน AOSP, แบบอักษร Arial ถูกต้อง แต่ต้องได้รับการกำหนดโดยใช้ "Arial" ไม่ "Arial" ตัวอย่างเช่นหุ่นยนต์: fontFamily = "Arial" ดู qucik ที่ system_fonts.xml ของ Kitkat

    <family>
    <nameset>
        <name>sans-serif</name>
        <name>arial</name>
        <name>helvetica</name>
        <name>tahoma</name>
        <name>verdana</name>
    </nameset>
    <fileset>
        <file>Roboto-Regular.ttf</file>
        <file>Roboto-Bold.ttf</file>
        <file>Roboto-Italic.ttf</file>
        <file>Roboto-BoldItalic.ttf</file>
    </fileset>
</family>

////////////////////////////////////////////////// ////////////////////////

มีสาม XML-คุณลักษณะที่เกี่ยวข้องสำหรับการกำหนดเป็น "ตัวอักษร" ใน layout-- เป็นหุ่นยนต์: fontFamily , หุ่นยนต์: อักษรและหุ่นยนต์: textstyle การรวมกันของ "fontFamily" และ "textStyle" หรือ "typeface" และ "textStyle" สามารถนำมาใช้เพื่อเปลี่ยนลักษณะที่ปรากฏของตัวอักษรในข้อความจึงใช้เพียงอย่างเดียว ข้อมูลโค้ดในTextView.javaเช่นนี้:

    private void setTypefaceFromAttrs(String familyName, int typefaceIndex, int styleIndex) {
    Typeface tf = null;
    if (familyName != null) {
        tf = Typeface.create(familyName, styleIndex);
        if (tf != null) {
            setTypeface(tf);
            return;
        }
    }
    switch (typefaceIndex) {
        case SANS:
            tf = Typeface.SANS_SERIF;
            break;

        case SERIF:
            tf = Typeface.SERIF;
            break;

        case MONOSPACE:
            tf = Typeface.MONOSPACE;
            break;
    }
    setTypeface(tf, styleIndex);
}


    public void setTypeface(Typeface tf, int style) {
    if (style > 0) {
        if (tf == null) {
            tf = Typeface.defaultFromStyle(style);
        } else {
            tf = Typeface.create(tf, style);
        }

        setTypeface(tf);
        // now compute what (if any) algorithmic styling is needed
        int typefaceStyle = tf != null ? tf.getStyle() : 0;
        int need = style & ~typefaceStyle;
        mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
        mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
    } else {
        mTextPaint.setFakeBoldText(false);
        mTextPaint.setTextSkewX(0);
        setTypeface(tf);
    }
}

จากรหัสเราสามารถดู:

  1. หากตั้งค่า "fontFamily" แล้ว "typeface" จะถูกละเว้น
  2. "typeface" มีค่าที่ถูกต้องตามมาตรฐานและ จำกัด ในความเป็นจริงค่าคือ "ปกติ" "sans" "serif" และ "monospace" ซึ่งสามารถพบได้ใน system_fonts.xml (4.x) หรือ fonts.xml (5.x) ที่จริงทั้ง "ปกติ" และ "ซอง" เป็นแบบอักษรเริ่มต้นของระบบ
  3. "fontFamily" สามารถใช้เพื่อตั้งค่าฟอนต์บิวด์อินทั้งหมดในขณะที่ "ฟอนต์" ให้เฉพาะฟอนต์ทั่วไปของ "sans-serif" "serif" และ "monospace" (ประเภทฟอนต์หลักสามประเภทในโลก) .
  4. เมื่อตั้งค่า "textStyle" เท่านั้นเราจะตั้งค่าฟอนต์เริ่มต้นและสไตล์ที่ระบุ ค่าที่มีประสิทธิภาพคือ "ปกติ" "ตัวหนา" "ตัวเอียง" และ "ตัวหนา | ตัวเอียง"

4

นี่เป็นวา y ที่ง่ายขึ้นที่สามารถทำงานได้ในบางกรณี หลักการคือการเพิ่ม TextVview ที่มองไม่เห็นในเลย์เอาต์ xml ของคุณและเพื่อรับ typeFaceในโค้ดจาวา

โครงร่างในไฟล์ xml:

 <TextView
        android:text="The classic bread is made of flour hot and salty. The classic bread is made of flour hot and salty. The classic bread is made of flour hot and salty."
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:fontFamily="sans-serif-thin"
        android:id="@+id/textViewDescription"/>

และรหัส java:

myText.setTypeface(textViewSelectedDescription.getTypeface());

มันใช้งานได้สำหรับฉัน (ภายใน TextSwitcher เป็นต้น)


4

ลองสิ่งนี้:

TextView textview = (TextView) findViewById(R.id.textview);

Typeface tf= Typeface.createFromAsset(getAssets(),"fonts/Tahoma.ttf");
textview .setTypeface(tf);

4

คุณสามารถทำได้โดยเพิ่มโฟลเดอร์ฟอนต์ภายใต้ไดเรกทอรี res ดังนี้

ป้อนคำอธิบายรูปภาพที่นี่

จากนั้นเลือกแบบอักษรเป็นประเภททรัพยากร ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถค้นหาแบบอักษรที่มีให้เลือกได้จากhttps://www.1001fonts.com/จากนั้นแยกไฟล์ TTF ไปยังไดเรกทอรีแบบอักษรนี้

ป้อนคำอธิบายรูปภาพที่นี่

สุดท้ายเพียงแค่เปลี่ยนไฟล์ XML ที่มี textview ของคุณโดยเพิ่ม android: fontFamily: "@ font / urfontfilename"

ป้อนคำอธิบายรูปภาพที่นี่


ดีมากขอบคุณสำหรับสิ่งนี้ idk ทำไมคนอื่นถึงมีดาวมากกว่านี้ แต่คุณได้รับการยืนยันให้ทำงานกับมุมมองข้อความการออกแบบวัสดุคุณต้องใช้app:fontFamily=อย่างไรก็ตามทุกอย่างเหมือนกัน
EvOlaNdLuPiZ

คุณช่วยชีวิตฉันไว้ฉันเพิ่งสร้างโฟลเดอร์ชื่อตัวอักษรและใช้งานไม่ได้ อย่างไรก็ตามฉันใช้วิธีการของคุณและมันก็ใช้ได้ขอบคุณ
Hilal

4

วิธีง่ายๆอย่างหนึ่งคือการเพิ่มแบบอักษรที่ต้องการในโครงการ

ไปที่File-> New-> New Resource Directory เลือกแบบอักษร

สิ่งนี้จะสร้างไดเรกทอรีใหม่แบบอักษรในแหล่งข้อมูลของคุณ

ดาวน์โหลดของคุณอักษร (.ttf) ฉันใช้https://fonts.google.comเหมือนกัน

เพิ่มลงในโฟลเดอร์ฟอนต์ของคุณจากนั้นใช้ใน XML หรือโดยทางโปรแกรม

XML -

<TextView 
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/your_font"/>

เชิงโปรแกรม -

 Typeface typeface = getResources().getFont(R.font.your_font);
 textView.setTypeface(typeface); 

9
ResourcesCompat.getFontวิธีการใช้ที่ดีกว่า
Vadim Kotov

3
<string name="font_family_display_4_material">sans-serif-light</string>
<string name="font_family_display_3_material">sans-serif</string>
<string name="font_family_display_2_material">sans-serif</string>
<string name="font_family_display_1_material">sans-serif</string>
<string name="font_family_headline_material">sans-serif</string>
<string name="font_family_title_material">sans-serif-medium</string>
<string name="font_family_subhead_material">sans-serif</string>
<string name="font_family_menu_material">sans-serif</string>
<string name="font_family_body_2_material">sans-serif-medium</string>
<string name="font_family_body_1_material">sans-serif</string>
<string name="font_family_caption_material">sans-serif</string>
<string name="font_family_button_material">sans-serif-medium</string>

3

หากคุณต้องการใช้ TextView ในหลาย ๆ ที่ที่มีตระกูลฟอนต์เดียวกันให้ขยายคลาส TextView และตั้งค่าฟอนต์ของคุณดังนี้: -

public class ProximaNovaTextView extends TextView {

    public ProximaNovaTextView(Context context) {
        super(context);

        applyCustomFont(context);
    }

    public ProximaNovaTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        applyCustomFont(context);
    }

    public ProximaNovaTextView(Context context, AttributeSet attrs, int defStyle) {
       super(context, attrs, defStyle);

       applyCustomFont(context);
    } 

    private void applyCustomFont(Context context) {
        Typeface customFont = FontCache.getTypeface("proximanova_regular.otf", context);
        setTypeface(customFont);
    }
}

จากนั้นใช้คลาสที่กำหนดเองนี้ใน xml สำหรับ TextView เช่นนี้: -

   <com.myapp.customview.ProximaNovaTextView
        android:id="@+id/feed_list_item_name_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        />

3

หากคุณใช้ Android Studio 3.5+ การเปลี่ยนแบบอักษรนั้นง่ายมาก เลือกวิดเจ็ตข้อความในมุมมองออกแบบและตรวจสอบ fontFamily บนหน้าต่างคุณสมบัติ ดรอปดาวน์ของค่าจะมีแบบอักษรทั้งหมดที่คุณสามารถเลือกได้ หากคุณกำลังมองหา Google แบบอักษรคลิกตัวเลือกแบบอักษรเพิ่มเติม

หน้าต่างคุณสมบัติ หน้าต่างคุณสมบัติ

Google แบบอักษร Google แบบอักษร


2

ฉันแค่อยากจะบอกว่านรกที่มีตัวอักษรใน Android กำลังจะหมดลงเพราะในปีนี้ใน Google IO เราได้รับสิ่งนี้ -> https://developer.android.com/preview/features/working-with-fonts HTML

ขณะนี้มีทรัพยากรใหม่ให้พิมพ์แบบอักษรและคุณสามารถวางแบบอักษรแอปพลิเคชันทั้งหมดของคุณในโฟลเดอร์ res / fonts และเข้าถึงจากนั้นใช้ R.font.my_custom_font เช่นเดียวกับที่คุณสามารถเข้าถึงค่าความละเอียดของสตริงค่าความละเอียดdrawableเป็นต้นคุณมีโอกาส เพื่อสร้างไฟล์ xml แบบอักษร - หน้าซึ่งจะถูกตั้งค่าแบบอักษรที่คุณกำหนดเอง (เกี่ยวกับตัวเอียงตัวหนาและขีดเส้นใต้ attr)

อ่านลิงค์ด้านบนสำหรับข้อมูลเพิ่มเติม มาดูการสนับสนุนกัน


น่าเสียดายที่นี่ยังไม่สามารถใช้งานได้กับ IntelliJ (แม้ว่าจะใช้งานได้ดีใน Android Studio 3.0+)
Dominikus K.

ใช่ แต่Redmanคำตอบของผู้ใช้ข้างต้นยังคงเป็นส่วนที่จำเป็นอย่างมากในการแก้ปัญหา
jungledev

2

มีห้องสมุดที่ดีสำหรับสิ่งนี้

    implementation 'uk.co.chrisjenx:calligraphy:2.3.0'

ไลบรารีนี้ isu ใช้เพื่อเปลี่ยนแบบอักษรของมุมมองทั้งหมดในแอปพลิเคชันทั้งหมด สิ่งนี้ไม่สามารถใช้ได้กับมุมมองอะแดปเตอร์เช่นมุมมองรายการ เพื่อที่เราจะต้องเพิ่มรหัสในแต่ละอะแดปเตอร์โดยเฉพาะ
Senthilvel S

2

ทรัพยากรแบบอักษรใหม่อนุญาตให้ตั้งค่าfontโดยใช้โดยตรง

android:fontFamily="@font/my_font_in_font_folder"

1

คุณกำหนดสไตล์ในres/layout/value/style.xmlแบบนั้น:

<style name="boldText">
    <item name="android:textStyle">bold|italic</item>
    <item name="android:textColor">#FFFFFF</item>
</style>

และใช้สไตล์นี้ในการmain.xmlใช้ไฟล์:

style="@style/boldText"

1

สำหรับ android-studio 3 ขึ้นไปคุณสามารถใช้สไตล์นี้แล้วtextViewเปลี่ยนแบบอักษรทั้งหมดในแอพ

สร้างสไตล์นี้ในstyle.xml:

<!--OverRide all textView font-->
<style name="defaultTextViewStyle" parent="android:Widget.TextView">
        <item name="android:fontFamily">@font/your_custom_font</item>
</style>

จากนั้นใช้ในธีมของคุณ:

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textViewStyle">@style/defaultTextViewStyle</item>
    </style>

1

วิธีที่ง่ายที่สุดในการเพิ่มแบบอักษรโดยทางโปรแกรมไปยัง TextViewคือก่อนอื่นให้เพิ่มไฟล์แบบอักษรในโฟลเดอร์ทรัพย์สินของคุณในโครงการ ตัวอย่างเช่นเส้นทางตัวอักษรของคุณมีลักษณะเช่นนี้:assets/fonts/my_font.otf

และเพิ่มลงใน TextView เป็น:

Kotlin

val font_path = "fonts/my_font.otf"  

myTypeface = Typeface.createFromAsset(MyApplication.getInstance().assets, font_path)

textView.typeface = myTypeface

ชวา

String font_path = "fonts/my_font.otf";
Typeface myTypeface = Typeface.createFromAsset(MyApplication.getInstance().assets, font_path)
textView.setTypeface(myTypeface);

0

ที่นี่คุณสามารถดูค่า fontFamily ที่มีให้เลือกทั้งหมดและเป็นชื่อของไฟล์ฟอนต์ที่เกี่ยวข้อง (ไฟล์นี้ใช้ใน Android 5.0+) ในอุปกรณ์มือถือคุณสามารถค้นหาได้ใน:

/system/etc/fonts.xml (สำหรับ 5.0+)

(สำหรับ android 4.4 และรุ่นต่ำกว่าที่ใช้รุ่นนี้แต่ฉันคิดว่ามันfonts.xmlมีรูปแบบที่ชัดเจนและเข้าใจง่าย)

ตัวอย่างเช่น,

    <!-- first font is default -->
20    <family name="sans-serif">
21        <font weight="100" style="normal">Roboto-Thin.ttf</font>
22        <font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
23        <font weight="300" style="normal">Roboto-Light.ttf</font>
24        <font weight="300" style="italic">Roboto-LightItalic.ttf</font>
25        <font weight="400" style="normal">Roboto-Regular.ttf</font>
26        <font weight="400" style="italic">Roboto-Italic.ttf</font>
27        <font weight="500" style="normal">Roboto-Medium.ttf</font>
28        <font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
29        <font weight="900" style="normal">Roboto-Black.ttf</font>
30        <font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
31        <font weight="700" style="normal">Roboto-Bold.ttf</font>
32        <font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
33    </family>

แอตทริบิวต์ name name="sans-serif"ของfamilyแท็กกำหนดค่าที่คุณสามารถใช้ใน android: fontFamily

fontแท็กกำหนดไฟล์ font ที่สอดคล้องกับ

ในกรณีนี้คุณสามารถละเว้นแหล่งที่มาภายใต้<!-- fallback fonts -->ซึ่งใช้สำหรับตรรกะทางเลือกของฟอนต์

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