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


266

Я применил пользовательский шрифт к a TextView, но, похоже, он не меняет гарнитуру.

Вот мой код:

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

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


1
В вашем синтаксисе есть ошибка, должно бытьmyTextView.setTypeface(myTypeface);
yuttadhammo

Эта тема похожа на: stackoverflow.com/a/14558090/693752
Сниколас

Посмотрите на рабочий пример javatechig.com/2013/03/19/using-external-fonts-in-android-view
Nilanchal


Здесь у вас есть эффективный способ изменить шрифт для всего приложения: stackoverflow.com/questions/18847531/…
Диего Паломар

Ответы:


230

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

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

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

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


Отредактировал мой ответ с решением сейчас.
Октавиан А. Дамиан

Не могли бы вы прислать мне какой-нибудь рабочий демонстрационный проект? Я пробовал в папке assets / fonts / xyz.ttf и assets / xyz.ttf, но он не принимает этот шрифт. Он отображает только шрифт по умолчанию ..
RATTLESNAKE

2
Конечно, здесь ссылка на заархивированный проект. dl.dropbox.com/u/8288893/customFont.zip
Октавиан А. Дамиан

5
Если вы следуете этому учебнику, убедитесь, что вы используете путь Typeface.createFromAsset (getAssets (), "fonts / yourfont.ttf"); если вы поместили его в подкаталог шрифтов
Jameo

не включайте «assets /» в имя файла (потому что createFromAssetфункция напрямую указывает на assetsкаталог)
topher

55

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

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

1
Какой размер этой библиотеки - важный вопрос, потому что это повлияет на размер приложения.
eRaisedToX

32

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

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

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>

Что customAttrsотносится к моему проекту?
Скайнет

@Skynet это относится к пространству имен, определенному в вашем корневом представлении xmlns:customAttrs="http://schemas.android.com/apk/res-auto". Это автоматически получает атрибуты, установленные для пользовательских представлений. В этом случае у вас есть атрибут customFont, определенный в attrs.xml. Более простой способ понять, что это за xmlns:android="http://schemas.android.com/apk/res/android"определение пространства имен для ваших атрибутов android. Так что, если бы вы изменили это на aто, а не на android:textэто a:text.
CodyEngel

14

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


13

При условии, что вы поместили шрифт в нужное место и в самом файле шрифта нет ошибки, ваш код должен работать так, 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 или посмотрите этот пост в блоге, который объясняет все это.


13

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

это работает, только если у вас есть Android Studio-2.4 или выше

  1. Щелкните правой кнопкой мыши Рез папки и перейдите в New> каталог Android ресурсов . Откроется
    окно «Новый каталог ресурсов».
  2. В списке Тип ресурса выберите шрифт и нажмите кнопку ОК.
  3. Добавить файлы шрифтов в папку шрифтов .The папку структуры ниже генерирует 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"/>

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

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

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


4
ony api> 26 ((
maXp


Это пропускает довольно большой шаг № 3 ... Как ты это делаешь?
Код Wiget

12

Для пользовательских шрифтов в 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);

7

Вы можете использовать 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" />

4

Поскольку я не был удовлетворен всеми представленными решениями на 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;
    }
}

4

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

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

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

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

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

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

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


2

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


2

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

2

Вы можете использовать легкую и простую стороннюю библиотеку 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
  • Зеленый авокадо
  • признание

1

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


1

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

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

1

Ну, через семь лет вы можете легко изменить все приложение 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 И это широкий спектр.


1

Обновить ответ: 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;
    }

}



0
  • Откройте свой проект и выберите Проект в левом верхнем углу
  • 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);

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


0

Да, загружаемые шрифты так просты, как Dipali сказал .

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

  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


Вы должны были бы оценить мой ответ, чем! :)
Дипали с.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.