Android - Использование собственного шрифта

Я применил собственный шрифт к TextView, но это, кажется, не меняет шрифт.

Вот мой код:

    Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
    TextView myTextView = (TextView)findViewById(R.id.myTextView);
    myTextView.setTypeface(myTypeface);

Кто-нибудь может вытащить меня из этого вопроса?

21 ответ

Решение

На Mobiletuts+ есть очень хорошее руководство по форматированию текста для Android. Совет: настройте шрифты Android

РЕДАКТИРОВАТЬ: Теперь проверил это сам. Вот решение. Вы можете использовать подпапку, называемую шрифтами, но она должна идти в assets папка не res папка. Так

активы / шрифты

Также убедитесь, что окончание шрифта, я имею в виду окончание самого файла шрифта, все в нижнем регистре. Другими словами это не должно быть myFont.TTF но myfont.ttf этот путь должен быть в нижнем регистре

Попробовав большинство решений, описанных в этой теме, я случайно обнаружил Calligraphy ( https://github.com/chrisjenx/Calligraphy) - библиотеку Кристофера Дженкинса, которая позволяет легко добавлять пользовательские шрифты в ваше приложение. Преимущества его библиотеки по сравнению с подходами, предложенными здесь:

  1. вам не нужно вводить свой собственный переопределенный компонент TextView, вы используете встроенный TextView
  2. Вы можете легко включить библиотеку, используя Gradle
  3. Библиотека не ограничивает ваш выбор шрифтов; Вы просто добавляете свои предпочтительные в каталог активов
  4. Вы не только получаете пользовательские текстовые представления - все другие текстовые компоненты Android также будут отображаться с использованием вашего собственного шрифта.

Я знаю, что уже есть хорошие ответы, но вот полностью рабочая реализация.

Вот пользовательский вид текста:

package com.mycompany.myapp.widget;

/**
 * Text view with a custom font.
 * <p/>
 * In the XML, use something like {@code customAttrs:customFont="roboto-thin"}. The list of fonts
 * that are currently supported are defined in the enum {@link CustomFont}. Remember to also add
 * {@code xmlns:customAttrs="http://schemas.android.com/apk/res-auto"} in the header.
 */
public class CustomFontTextView extends TextView {

    private static final String sScheme =
            "http://schemas.android.com/apk/res-auto";
    private static final String sAttribute = "customFont";

    static enum CustomFont {
        ROBOTO_THIN("fonts/Roboto-Thin.ttf"),
        ROBOTO_LIGHT("fonts/Roboto-Light.ttf");

        private final String fileName;

        CustomFont(String fileName) {
            this.fileName = fileName;
        }

        static CustomFont fromString(String fontName) {
            return CustomFont.valueOf(fontName.toUpperCase(Locale.US));
        }

        public Typeface asTypeface(Context context) {
            return Typeface.createFromAsset(context.getAssets(), fileName);
        }
    }

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

        if (isInEditMode()) {
            return;
        } else {
            final String fontName = attrs.getAttributeValue(sScheme, sAttribute);

            if (fontName == null) {
                throw new IllegalArgumentException("You must provide \"" + sAttribute + "\" for your text view");
            } else {
                final Typeface customTypeface = CustomFont.fromString(fontName).asTypeface(context);
                setTypeface(customTypeface);
            }
        }
    }
}

Вот пользовательские атрибуты. Это должно идти к вашему res/attrs.xml файл:

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

И вот как вы это используете. Я буду использовать относительный макет, чтобы обернуть его и показать customAttr декларации, но это может быть любой макет, который у вас уже есть.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:customAttrs="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.mycompany.myapp.widget.CustomFontTextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="foobar"
         customAttrs:customFont="roboto_thin" />

</RelativeLayout>

Лучший способ сделать это из предварительной версии Android O:

Работает только если у вас андроид студия-2.4 или выше

  1. Щелкните правой кнопкой мыши папку res и выберите " Создать"> "Каталог ресурсов Android". Новый
    Откроется окно каталога ресурсов.
  2. В списке Тип ресурса выберите шрифт и нажмите кнопку ОК.
  3. Добавьте ваши файлы шрифтов в папку шрифтов. Структура папок ниже генерирует R.font.dancing_script, R.font.la_la, а также R.font.ba_ba,
  4. Дважды щелкните файл шрифта, чтобы просмотреть шрифты файла в редакторе.

Далее мы должны создать семейство шрифтов:

  1. Щелкните правой кнопкой мыши папку шрифтов и выберите " Создать"> "Файл ресурсов шрифта". Откроется окно "Новый файл ресурсов".
  2. Введите имя файла и нажмите кнопку ОК. Новый ресурс шрифта XML открывается в редакторе.
  3. Включите каждый файл шрифта, стиль и атрибут веса в элемент тега шрифта. Следующий XML-код иллюстрирует добавление связанных со шрифтом атрибутов в XML-код ресурса шрифта:

Добавление шрифтов в TextView:

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

Как из документации

Работа со шрифтами

Все шаги верны.

Я успешно использовал это раньше. Единственная разница между нашими реализациями состоит в том, что я не использовал подпапку в активах. Не уверен, что это что-то изменит, хотя.

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

Однако было бы намного проще, если бы вы могли просто определить шрифт в вашем макете XML, например так:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <!-- This text view is styled with the app theme -->
    <com.innovattic.font.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This uses my font in bold italic style" />

    <!-- This text view is styled here and overrides the app theme -->
    <com.innovattic.font.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:flFont="anotherFont"
        android:textStyle="normal"
        android:text="This uses another font in normal style" />

    <!-- This text view is styled with a style and overrides the app theme -->
    <com.innovattic.font.FontTextView
        style="@style/StylishFont"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This also uses another font in normal style" />

</LinearLayout>

С сопровождающим res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <!-- Application theme -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <item name="android:textViewStyle">@style/MyTextViewStyle</item>
    </style>

    <!-- Style to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextViewStyle" parent="@android:style/Widget.Holo.Light.TextView">
        <item name="android:textAppearance">@style/MyTextAppearance</item>
    </style>

    <!-- Text appearance to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextAppearance" parent="@android:style/TextAppearance.Holo">
        <!-- Alternatively, reference this font with the name "aspergit" -->
        <!-- Note that only our own TextView's will use the font attribute -->
        <item name="flFont">someFont</item>
        <item name="android:textStyle">bold|italic</item>
    </style>

    <!-- Alternative style, maybe for some other widget -->
    <style name="StylishFont">
        <item name="flFont">anotherFont</item>
        <item name="android:textStyle">normal</item>
    </style>

</resources>

Я создал несколько инструментов специально для этой цели. Обратитесь к этому проекту от GitHub или посмотрите этот пост в блоге, который объясняет все это.

Для пользовательских шрифтов в Android создайте папку с именем папки с ресурсами, в ней "шрифты" поместите нужный файл fonts.ttf или.otf.

Если вы расширяете UIBaseFragment:

Typeface font = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Arial.ttf");
        tv.setTypeface(font);

еще, если расширяет активность:

Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/Arial.ttf");
        tv.setTypeface(font);

Вы можете использовать PixlUI по адресу https://github.com/neopixl/PixlUI

импортировать их.jar и использовать его в XML

 <com.neopixl.pixlui.components.textview.TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    pixlui:typeface="GearedSlab.ttf" />

К сожалению, нет хорошего решения для этого.

Я видел много статей об использовании пользовательского TextView, но что они забывают, так это то, что не только текстовые представления могут реализовывать шрифты, но и текстовые представления скрыты в других представлениях, недоступных для разработчика; Я даже не собираюсь начинать Spannable.

Вы можете использовать утилиту внешнего шрифта, например:

Каллиграфический шрифт

НО Это зацикливается на каждом представлении в приложении при его создании, и даже эта утилита пропускает некоторые представления (ViewPager отображает обычный шрифт), тогда у вас возникает проблема, заключающаяся в том, что, когда Google обновляет свои инструменты сборки, это иногда приводит к сбою, так как ему нужно ориентироваться на устаревшие свойства. Он также немного медленный, поскольку использует отражение Java.

Это действительно зависит от Google, чтобы исправить это. Нам нужна лучшая поддержка шрифтов в Android. Если вы посмотрите на решение от iOS, у них буквально есть сотни встроенных шрифтов на выбор. Хотите нестандартный шрифт? Просто вставьте TFF, и это пригодится...

На данный момент были ограничены предложением, которое предлагает нам Google, которое чрезвычайно ограничено, но, к счастью, оптимизировано для мобильных устройств.

Поскольку я не был удовлетворен всеми представленными решениями на SO, я придумал свои. Он основан на небольшом трюке с тегами (то есть вы не можете использовать теги в своем коде), я поместил туда путь к шрифту. Поэтому при определении представлений вы можете сделать следующее:

<TextView
        android:id="@+id/textViewHello1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World 1"
        android:tag="fonts/Oswald-Regular.ttf"/>

или это:

<TextView
        android:id="@+id/textViewHello2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World 2"
        style="@style/OswaldTextAppearance"/>

<style name="OswaldTextAppearance">
        <item name="android:tag">fonts/Oswald-Regular.ttf</item>
        <item name="android:textColor">#000000</item>
</style>

Теперь вы можете явно открыть / настроить вид как:

TextView textView = TextViewHelper.setupTextView(this, R.id.textViewHello1).setText("blah");

или просто настроить все через:

TextViewHelper.setupTextViews(this, (ViewGroup) findViewById(R.id.parentLayout)); // parentLayout is the root view group (relative layout in my case)

А какой урок магии вы спрашиваете? В основном склеены из других сообщений SO, с помощью вспомогательных методов для активности и фрагментов:

import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.HashMap;
import java.util.Map;

public class TextViewHelper {
    private static final Map<String, Typeface> mFontCache = new HashMap<>();

    private static Typeface getTypeface(Context context, String fontPath) {
        Typeface typeface;
        if (mFontCache.containsKey(fontPath)) {
            typeface = mFontCache.get(fontPath);
        } else {
            typeface = Typeface.createFromAsset(context.getAssets(), fontPath);
            mFontCache.put(fontPath, typeface);
        }
        return typeface;
    }

    public static void setupTextViews(Context context, ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setupTextViews(context, (ViewGroup) child);
            } else {
                if (child != null) {
                    TextViewHelper.setupTextView(context, child);
                }
            }
        }
    }

    public static void setupTextView(Context context, View view) {
        if (view instanceof TextView) {
            if (view.getTag() != null) // also inherited from TextView's style
            {
                TextView textView = (TextView) view;
                String fontPath = (String) textView.getTag();
                Typeface typeface = getTypeface(context, fontPath);
                if (typeface != null) {
                    textView.setTypeface(typeface);
                }
            }
        }
    }

    public static TextView setupTextView(View rootView, int id) {
        TextView textView = (TextView) rootView.findViewById(id);
        setupTextView(rootView.getContext().getApplicationContext(), textView);
        return textView;
    }

    public static TextView setupTextView(Activity activity, int id) {
        TextView textView = (TextView) activity.findViewById(id);
        setupTextView(activity.getApplicationContext(), textView);
        return textView;
    }
}

Обязательно вставьте приведенный выше код в onCreate() после вызова супер и вызова setContentView(). Эта маленькая деталь удерживала меня на некоторое время.

Вы можете использовать легкую и простую стороннюю библиотеку EasyFonts для установки различных пользовательских шрифтов на свой TextView, Используя эту библиотеку, вам не нужно беспокоиться о загрузке и добавлении шрифтов в папку assets/fonts. Также о создании объекта гарнитуры.

Вместо

Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(myTypeface);

Просто:

TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(EasyFonts.robotoThin(this));

Эта библиотека также обеспечивает следующий шрифт лица.

  • Roboto
  • Дроид с засечками
  • Робот-дроид
  • свобода
  • Fun Raiser
  • Android Nation
  • Зеленый авокадо
  • признание

Я автор этой библиотеки.

С Android 8.0 использование пользовательских шрифтов в приложении стало проще с downloadable fonts, Мы можем добавить шрифты прямо в res/font/ folder в папке проекта, и при этом шрифты автоматически становятся доступными в Android Studio.

Папка под res с именем шрифта и типом установлено в Font

Сейчас установлено fontFamily Приписать список шрифтов или нажмите больше и выберите шрифт по вашему выбору. Это добавит tools:fontFamily="@font/your_font_file" линия к вашему TextView.

Это автоматически сгенерирует несколько файлов.

1. В папке значений он создаст fonts_certs.xml,

2. В Manifest он добавит следующие строки:

  <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" /> 

3. preloaded_fonts.xml

<resources>
    <array name="preloaded_fonts" translatable="false">
        <item>@font/open_sans_regular</item>
        <item>@font/open_sans_semibold</item>
    </array>
</resources>

Если вы хотите загрузить шрифт из сети или легко стилизовать его, вы можете использовать:

https://github.com/shellum/fontView

Пример:

<!--Layout-->
<com.finalhack.fontview.FontView
        android:id="@+id/someFontIcon"
        android:layout_width="80dp"
        android:layout_height="80dp" />

//Java:
fontView.setupFont("http://blah.com/myfont.ttf", true, character, FontView.ImageType.CIRCLE);
fontView.addForegroundColor(Color.RED);
fontView.addBackgroundColor(Color.WHITE);

Обновление ответа: Android 8.0 (уровень API 26) представляет новую функцию "Шрифты в XML". просто используйте функцию "Шрифты в XML" на устройствах под управлением Android 4.1 (уровень API 16) и выше, используйте библиотеку поддержки 26.

см эту ссылку


Старый ответ

Есть два способа настроить шрифты:

!!! мой пользовательский шрифт в assets/fonts/iran_sans.ttf



Способ 1: Refrection Typeface.class ||| лучший способ

вызов FontsOverride.setDefaultFont() в классе расширяет приложение, этот код приведет к изменению всех программных шрифтов, даже шрифтов Toasts

AppController.java

public class AppController extends Application {

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

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

    }
}

FontsOverride.java

public class FontsOverride {

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

    private static void replaceFont(String staticTypefaceFieldName, final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class.getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}



Способ 2: использовать setTypeface

для особого просмотра просто вызовите setTypeface(), чтобы изменить шрифт.

CTextView.java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.java

public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}

Ну, через семь лет вы можете изменить все приложение textView или что вы хотите легко с помощью android.support библиотеки 26++.

Например:

Создайте свой пакет шрифтов app/src/res/font и переместите в него свой шрифт.

А в теме вашего приложения просто добавьте его как fontFamily:

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

Пример для использования с textView только:

<style name="fontTextView" parent="@android:style/Widget.TextView">
    <item name="android:fontFamily">monospace</item>
</style>

И добавьте в свою главную тему:

<item name="android:textViewStyle">@style/fontTextView</item>

В настоящее время он работает на 8.1 до 4.1 API Jelly Bean И это широкий спектр.

У меня была такая же проблема, TTF не появился. Я изменил файл шрифта, и с тем же кодом он работает.

Да, скачиваемые шрифты так просты, как сказал Дипали.

Вот как ты это делаешь...

  1. Поместите TextView,
  2. На панели свойств выберите fontFamily падать. Если его там нет, найдите каретку (> и нажмите на нее, чтобы развернуть textAppearance) под.
  3. Разверните font-family падать.
  4. В маленьком списке прокрутите вниз, пока не увидите more fonts
  5. Это откроет диалоговое окно, где вы можете искать из Google Fonts
  6. Найдите понравившийся шрифт с помощью строки поиска вверху
  7. Выберите свой шрифт.
  8. Выберите стиль шрифта, который вам нравится (например, жирный, обычный, курсив и т. Д.)
  9. На правой панели выберите переключатель, который говорит Add font to project
  10. Нажмите хорошо. Теперь у вашего TextView есть шрифт, который вам нравится!

БОНУС: Если вы хотите добавить в текст ВСЕ текст выбранного приложения, просто добавьте <item name="android:fontfamily">@font/fontnamehere</item> в ваш styles.xml

Самое простое решение Android поддерживается сейчас!

Используйте пользовательский шрифт в XML:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/[your font resource]"/>

смотреть детали:

https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

  • Откройте свой проект и выберите Проект в левом верхнем углу
  • app -> src -> main
  • щелкните правой кнопкой мыши на главном и создайте имя каталога как активы
  • щелкните правой кнопкой мыши, чтобы собрать и создать новый каталог имя шрифты
  • вам нужно найти бесплатные шрифты, как бесплатные шрифты
  • отдайте его вашему Textview и назовите его в вашем классе Activity
  • скопируйте ваши шрифты в папку шрифтов
  • TextView txt = (TextView) findViewById(R.id.txt_act_spalsh_welcome); Typeface font = Typeface.createFromAsset(getAssets(), "fonts/Aramis Italic.ttf"); txt.setTypeface(font);

название шрифта должно быть правильным и веселиться

Правильный способ сделать это с API 26 описан в официальной документации здесь:

https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

Это включает размещение файлов ttf в папке res / font и создание файла семейства шрифтов.

Другие вопросы по тегам