Як змінити шрифт "Родина 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"
 />

Здається, те, що я там зробив, насправді не спрацює! До речі, android:fontFamily="Arial"дурна спроба!


перевірити це посилання stackoverflow.com/questions/2376250 / ...
Дуггу

Відповіді:


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-Light курсивом
  • Робото-тонкий
  • Робото-тонкий курсив
  • Робото-конденсований
  • Робото-конденсований курсив
  • Робото-ущільнений жирний шрифт
  • Робото-конденсований жирний курсив
  • Робото-Чорний
  • Робото-чорний курсив
  • Робото-середній
  • Робото-середній курсив

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.
Крістофер Перрі

8
Остаточний список шрифтів можна знайти в system_fonts.xml, як пояснено тут
Newtonx

207

Це спосіб програмного встановлення шрифту:

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

помістіть файл шрифту у папку активів. У моєму випадку я створив підкаталог під назвою шрифти.

EDIT: Якщо вам цікаво, де знаходиться папка ваших активів, дивіться це питання


34
Хоча це працює, зауважте, що це може створити витік пам'яті . Це можна виправити за допомогою цієї відповіді .
Шарль Мадере

@ScootrNova я отримую цю помилку, коли використовую ваше рішення. Помилка: ресурс шрифту не знайдено gothic.ttf
Sagar Devanga

Як застосувати це до всього додатка? Зараз у прикладі ви застосовуєте його лише для перегляду тексту
Pritish Joshi

176

Починаючи з Android-Studio 3.0, його дуже легко змінити сімейство шрифтів

Використовуючи бібліотеку підтримки 26, вона працюватиме на пристроях, на яких працює Android API версії 16 та новішої

Створіть папку fontпід resкаталогом. Завантажте шрифт, який хочете, і вставте його всередину fontпапки. Структура повинна бути якоюсь річчю, як нижче

Ось

Примітка. Як і в бібліотеці підтримки Android 26.0, ви повинні оголосити обидва набори атрибутів (android: і app:), щоб забезпечити завантаження шрифтів на пристроях, на яких працює Api 26 або новішої версії.

Тепер ви можете змінити шрифт у макеті, використовуючи

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

Для того, щоб змінити Programatically

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

ви також можете створити власну сімейство шрифтів

- Клацніть правою кнопкою миші папку шрифту та перейдіть до пункту «Новий»> «Файл ресурсів шрифту» . З'явиться вікно Новий файл ресурсу.

- Введіть ім'я файлу та натисніть кнопку ОК . У редакторі відкриється новий ресурс шрифту 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. Сподіваюся, що хтось економить якийсь час!
Таш Пемхіва

2
Як ви могли отримати шрифт з фрагмента, оскільки ви не можете просто зробити це getResources()? EDIT : Цей рядок наприкінці вашої відповіді працював на мене: Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
Парадокс

Якось це зробило шрифт у моєму випадку зіпсованим, порівняно з Caligtraphy. Також fontWeight нічого не робить
Leo Droidcoder

@LeoDroidcoder це спрацює, переконайтесь, що ви використовували і те, android:fontWeightіapp:fontWeight
Манохар Редді

Я кілька разів перевіряв. Ефекту немає.
Лев Дродікодер

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              
╚════╩════════════════════════════╩═════════════════════════════╝

Ось аналізатор (заснований на 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 додала який шрифт?
андроїд розробник

@androiddeveloper Я не хочу. Можливо, ви могли це дізнатись, переглянувши зміни тут: github.com/android/platform_frameworks_base/blob/…
Джаред Румлер

@JredRummler, пробач моє незнання. Чому / Яка вага == 400?
Самуїл

1
@Samuel Я деякий час не переглядав цей код, але вага шрифту 400 використовується для "звичайних" або "звичайних" шрифтів. Наприклад, Roboto-Regular має вагу 400.
Джаред Раммлер

Для цього потрібен корінь чи щось таке? Я запустив цей код на емуляторі 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)
Чортові овочі

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.

вбудовані шрифти:

  • нормальний
  • sans
  • серіф
  • монопростір

Дивіться android: typeface .


4
Я не думаю, що це одне й те саме, але, здається, ми не можемо використовувати обидва. Здається, що зараз відображено не менше трьох різних атрибутів setTypeface(). А саме fontFamily, typefaceі textStyle. Але я не можу за все життя зрозуміти, як саме вони поєднуються для вирішення конкретного екземпляра Typeface. Хтось це зрозумів? Документація Google менш корисна ...
Рад Харінг

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

Я використовую відмінну бібліотечну каліграфію Кріса Дженкса, розроблену для того, щоб ви могли використовувати власні шрифти у вашому додатку для Android. Спробувати!


так, але, наприклад, я хочу використовувати його функціонально, але я не хочу реалізувати всю бібліотеку;)
Морозов

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"
андроїд розробник

Дякую, я використовую цей github.com/norbsoft/android-typeface-helper, і це дуже корисно
AZ_

добре, бібліотека, ймовірно, робить це програмно. ось це для XML
андроїд розробник

9

Динамічно ви можете встановити шрифт, схожий на 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 / активи / шрифти / mycustomfont.ttf , ви можете дізнатися більше про шрифт за замовчуванням у цій сім'ї шрифтів за замовчуванням


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

легко встановити шрифт для будь-якого перегляду тексту з res> директорії шрифтів програмно


7

Я думаю, що я запізнився, але, можливо, це рішення корисне для інших. Для використання спеціального шрифту розмістіть файл шрифту у своєму каталозі шрифтів.

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

6

З деякими спробами та помилками я дізнався наступне.

У межах * .xml ви можете комбінувати фондові шрифти із такими функціями, а не лише із шрифтом:

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

З цими двома стилями не було потреби використовувати шрифт у жодному іншому випадку. Спектр комбінацій значно більший за розмір шрифту та textStyle.


5

Дійсне значення android: fontFamily визначається в /system/etc/system_fonts.xml(4.x) або /system/etc/fonts.xml(5.x). Але Виробник пристрою може змінити його, тому власне шрифт, який використовується для встановлення значення fontFamily, залежить від згаданого вище файлу вказаного пристрою.

В AOSP шрифт Arial дійсний, але його слід визначити, використовуючи "arial", а не "Arial", наприклад, android: fontFamily = "arial" . Погляньте на квитик на 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 , андроїд: гарнітура і Android: 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", то "шрифт" буде ігноровано.
  2. "шрифт" має стандартні та обмежені допустимі значення. Насправді значення "нормальні" "sans" "serif" та "monospace", їх можна знайти в system_fonts.xml (4.x) або fonts.xml (5.x). Насправді як "normal", так і "sans" є шрифтом системи за замовчуванням.
  3. "fontFamily" можна використовувати для встановлення всіх шрифтів вбудованих шрифтів, тоді як "шрифт" надає лише типові шрифти "sans-serif" "serif" та "monospace" (три основні категорії типу шрифту у світі) .
  4. Якщо встановлюється лише "textStyle", ми фактично встановлюємо шрифт за замовчуванням та заданий стиль. Ефективними значеннями є "нормальний", "жирний", "курсив" та "жирний | курсив".

4

Ось простіший варіант, який може працювати в деяких випадках. Принцип полягає в тому, щоб додати не видимий TextVview у свій xml макет і отримати його typeFace в коді Java.

Макет у файлі 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, який містить ваше перегляд тексту, додавши android: fontFamily: "@ font / urfontfilename"

введіть тут опис зображення


дуже приємно, дякую за це. idk, чому інші мають більше зірок, але у вас підтверджено, що ви працюєте з текстовим оформленням тексту дизайну, але ви повинні використовувати, app:fontFamily=проте все інше те саме.
EvOlaNdLuPiZ

Ви врятували мені життя, я тільки що створив папку з назвою шрифту, і вона не працювала. У будь-якому випадку я використовував ваш шлях, і це спрацювало. Дякую
Хілал

4

Один простий спосіб - додавання потрібного шрифту в проект.

Перейдіть у меню Файл-> Створити-> Новий каталог ресурсів Виберіть шрифт

Це створить новий каталог, шрифт у ваших ресурсах.

Завантажте свій шрифт (.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); 

8
Кращий ResourcesCompat.getFontспосіб використання
Вадим Котов

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+, змінити шрифт - це дуже просто. Виберіть текстовий віджет у вікні «Дизайн» та перевірте шрифт «Сімейство у вікні атрибутів». Спадне значення містить усі доступні шрифти, з яких можна вибрати один. Якщо ви шукаєте шрифти Google, виберіть Більше шрифтів.

Вікно атрибутів Вікно атрибутів

Google Шрифти Google Шрифти


2

Я просто хочу зазначити, що чорт із шрифтами всередині Android вже закінчиться, тому що цього року на Google IO ми нарешті отримали це -> https://developer.android.com/preview/features/working-with-fonts. html

Тепер є новий ресурс ввести шрифт , і ви можете помістити всі шрифти додатки всередині рез / папку шрифтів і доступ потім з R.font.my_custom_font, так само , як ви можете отримати доступ до строковому Резу значення, малює разреш цінності і т.д. У вас є навіть шанс створити XML-файл шрифтового обличчя , який буде встановлений з ваших власних шрифтів (курсивом, жирним шрифтом та підкресленням attr).

Прочитайте посилання вище для отримання додаткової інформації. Давайте подивимось на підтримку.


На жаль, це все ще не працює з IntelliJ (хоча працює як шарм на Android Studio 3.0+).
Домінікус К.

Так, але Redmanвідповідь користувача вище, як і раніше, є дуже важливою частиною рішення.
jungledev

2

Для цього є приємна бібліотека

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

Ця бібліотека використовується для зміни шрифту всіх переглядів у всій програмі. Це не стосується переглядів адаптера, таких як перегляд списку. Для цього нам потрібно додати код у кожному адаптері конкретно
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 як:

Котлін

val font_path = "fonts/my_font.otf"  

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

textView.typeface = myTypeface

Java

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

(Для андроїда 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="sans-serif"зfamily тега визначається значення , яке ви можете використовувати в Android: FontFamily.

The fontТеги визначають листувалися файли шрифтів.

У цьому випадку ви можете проігнорувати джерело під <!-- fallback fonts -->, воно використовується для логіки резервного шрифту.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.