Как изменить шрифт семьи TextView в Android

740

Поэтому я хотел бы изменить 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/…
duggu

Ответы:

1661

Начиная с 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
  • Roboto-Light курсив
  • Roboto-тонкий
  • Робото-тонкий курсив
  • Roboto-Сгущенное
  • Роботоконденсированный курсив
  • Roboto-Condensed полужирный
  • Роботоконденсированный жирный курсив
  • 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" // роботизированный тонкий
Сэм Лу,
6
Я видел вариант под названием «черные маленькие шапочки» в книге образцов робото , но мне не удается его использовать. Использование android:fontFamily="sans-serif-black-small-caps"не работает. Кто-нибудь знает?
tbruyelle
3
Я не могу найти ни одного из этих семейств шрифтов, которые вы здесь напечатали. Я не могу найти «без засечек» вместе.
Монти
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);

поместите файл шрифта в папку с активами. В моем случае я создал подкаталог с именем шрифты.

РЕДАКТИРОВАТЬ: Если вам интересно, где находится ваша папка активов, посмотрите этот вопрос

Стефан Бейке
источник
34
Хотя это работает, обратите внимание, что это может привести к утечке памяти . Это можно исправить с помощью этого ответа .
Шарль Мадер,
@ScootrNova я получаю эту ошибку, когда я использую ваше решение. Ошибка: ресурс шрифта не найден gothic.ttf
Сагар Деванга
Как применить это ко всему приложению? Прямо сейчас в примере вы применяете его только на textview
Притиш Джоши
178

Начиная с 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"/>

Изменить программно

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

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 Custom Fonts для получения дополнительной информации

Манохар Редди
источник
7
Примечание: в настоящее время это работает только в Android Studio 3.0 Preview. У меня не работало на Android Studio 2.3.3. Надеюсь, это сэкономит кому-то время!
Таш Пемхива
2
Как вы можете получить шрифт из фрагмента, поскольку вы не можете просто сделать getResources()? РЕДАКТИРОВАТЬ : Эта строка в конце вашего ответа работал для меня: Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
Paradox
Каким-то образом это заставило шрифт выглядеть испорченным в моем случае, по сравнению с 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 добавила какой шрифт?
Android-разработчик
@ androiddeveloper Не знаю. Вы могли бы узнать это, просмотрев изменения здесь: github.com/android/platform_frameworks_base/blob/…
Джаред Раммлер,
@JaredRummler, прости мое невежество. Почему / Что такое вес == 400?
Самуил
1
@ Самуэль Я давно не смотрел этот код, но для «нормальных» или «обычных» шрифтов используется вес 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
Роджер Хуанг,
27

Чтобы установить Roboto программно:

paint.setTypeface(Typeface.create("sans-serif-thin", Typeface.NORMAL));
Одед Брейнер
источник
25

Это так же, как android:typeface.

Встроенные шрифты:

  • нормальный
  • без
  • засечка
  • моноширинный

Смотрите андроид: гарнитура .

biegleux
источник
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

Я использую отличную библиотеку Calligraphy от Chris Jenx, разработанную, чтобы позволить вам использовать пользовательские шрифты в вашем приложении для Android. Попробуйте!

gauravdott
источник
да, но, например, я хочу использовать это functionanl, но не хочу реализовывать всю библиотеку;)
Морозов
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>

Это основано на исходном коде здесь и здесь

разработчик Android
источник
Где их объявить?
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);

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

Makvin
источник
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», например, android: fontFamily = «arial» . Посмотрите qucik на system_fonts.xml Китката

    <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-атрибута для определения «шрифта» в макете : android: fontFamily , android: typeface и 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. «гарнитура» имеет стандартные и ограниченные допустимые значения. Фактически, значения являются «обычными», «без», «засечками» и «моноширинными», их можно найти в system_fonts.xml (4.x) или fonts.xml (5.x). На самом деле и «нормальный», и «без» являются шрифтом по умолчанию системы.
  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, как показано ниже.

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

Затем, выбрав Font в качестве типа ресурса. введите описание изображения здесь

Вы можете найти доступные шрифты на https://www.1001fonts.com/ , а затем распаковать файлы TTF в этот каталог шрифтов.

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

Наконец, просто измените XML-файл, содержащий ваше текстовое представление, добавив android: fontFamily: "@ font / urfontfilename"

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

Wolfiebae
источник
очень приятно, спасибо за это. Я знаю, почему у других есть больше звезд, но ваша работа с текстовым представлением дизайна подтверждена, но вы должны использовать app:fontFamily=все остальное так же.
EvOlaNdLuPiZ
Вы спасли мне жизнь, я только что создал папку с именем font, и она не работала. В любом случае, я использовал твой путь, и это сработало. Спасибо
Хилал
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); 
Аканши Шривастава
источник
9
Лучше использовать 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+, изменить шрифт очень просто. Выберите текстовый виджет в представлении «Дизайн» и проверьте fontFamily в окне «Атрибуты». Раскрывающееся значение содержит все доступные шрифты, из которых вы можете выбрать один. Если вы ищете Google Fonts, выберите опцию More Fonts.

Окно атрибутов Окно атрибутов

Google Fonts Google Fonts

Сива
источник
2

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

Теперь появился новый тип ресурса - шрифт, и вы можете поместить все свои шрифты приложения в папку res / fonts и затем обращаться к ним с помощью R.font.my_custom_font, точно так же, как вы можете получить доступ к строковым значениям res, рисуемым значениям res и т. Д. У вас даже есть шанс создать xml-файл font-face , в котором будут установлены ваши собственные шрифты (курсивом, жирным шрифтом и подчеркиванием).

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

Стойчо Андреев
источник
К сожалению, это по-прежнему не работает с 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

Ява

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

fontТеги определяют переписывались файлы шрифтов.

В этом случае вы можете игнорировать исходный код <!-- fallback fonts -->, он использует логику восстановления шрифтов.

Gnod
источник