Intereting Posts

Пользовательские шрифты и XML-макеты (Android)

Я пытаюсь определить макет графического интерфейса, используя XML-файлы в Android. Насколько я могу судить, нет способа указать, что ваши виджеты должны использовать пользовательский шрифт (например, тот, который вы разместили в файле / font /) в файлах XML, и вы можете использовать только установленные системой шрифты.

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

Какие еще варианты у меня есть? Есть ли лучшие способы создания виджетов, которые имеют пользовательский вид? Я не особо хочу, чтобы вручную менять шрифт для каждого нового добавляемого виджета.

Вы можете расширить TextView для установки пользовательских шрифтов, как я узнал здесь .

TextViewPlus.java:

package com.example; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Typeface; import android.util.AttributeSet; import android.util.Log; import android.widget.TextView; public class TextViewPlus extends TextView { private static final String TAG = "TextView"; public TextViewPlus(Context context) { super(context); } public TextViewPlus(Context context, AttributeSet attrs) { super(context, attrs); setCustomFont(context, attrs); } public TextViewPlus(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setCustomFont(context, attrs); } private void setCustomFont(Context ctx, AttributeSet attrs) { TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus); String customFont = a.getString(R.styleable.TextViewPlus_customFont); setCustomFont(ctx, customFont); a.recycle(); } public boolean setCustomFont(Context ctx, String asset) { Typeface tf = null; try { tf = Typeface.createFromAsset(ctx.getAssets(), asset); } catch (Exception e) { Log.e(TAG, "Could not get typeface: "+e.getMessage()); return false; } setTypeface(tf); return true; } } 

Attrs.xml: (в res / values)

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

main.xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:foo="http://schemas.android.com/apk/res/com.example" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.example.TextViewPlus android:id="@+id/textViewPlus1" android:layout_height="match_parent" android:layout_width="match_parent" android:text="@string/showingOffTheNewTypeface" foo:customFont="saxmono.ttf"> </com.example.TextViewPlus> </LinearLayout> 

Вы поместите «saxmono.ttf» в папку с ресурсами .

ОБНОВЛЕНИЕ 8/1/13

С этим методом возникают серьезные проблемы с памятью. См . Комментарий chedabob ниже.

Я опаздываю на вечеринку на 3 года 🙁 Однако это может быть полезно для кого-то, кто может наткнуться на этот пост.

Я написал библиотеку, которая кэширует Typefaces, а также позволяет указать пользовательские шрифты прямо из XML. Здесь вы можете найти библиотеку.

Вот как выглядит ваш XML-макет при его использовании.

 <com.mobsandgeeks.ui.TypefaceTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" geekui:customTypeface="fonts/custom_font.ttf" /> 

Это может быть немного поздно, но вам нужно создать одноэлементный класс, который возвращает пользовательский шрифт, чтобы избежать утечек памяти.

Класс TypeFace:

 public class OpenSans { private static OpenSans instance; private static Typeface typeface; public static OpenSans getInstance(Context context) { synchronized (OpenSans.class) { if (instance == null) { instance = new OpenSans(); typeface = Typeface.createFromAsset(context.getResources().getAssets(), "open_sans.ttf"); } return instance; } } public Typeface getTypeFace() { return typeface; } } 

Пользовательский TextView:

 public class NativelyCustomTextView extends TextView { public NativelyCustomTextView(Context context) { super(context); setTypeface(OpenSans.getInstance(context).getTypeFace()); } public NativelyCustomTextView(Context context, AttributeSet attrs) { super(context, attrs); setTypeface(OpenSans.getInstance(context).getTypeFace()); } public NativelyCustomTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setTypeface(OpenSans.getInstance(context).getTypeFace()); } } 

По xml:

 <com.yourpackage.views.NativelyCustomTextView android:id="@+id/natively_text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_margin="20dp" android:text="@string/natively" android:textSize="30sp" /> 

Программный:

 TextView programmaticallyTextView = (TextView) findViewById(R.id.programmatically_text_view); programmaticallyTextView.setTypeface(OpenSans.getInstance(this) .getTypeFace()); 

Старый вопрос, но я, конечно, хочу, чтобы я прочитал этот ответ здесь, прежде чем начал свой собственный поиск хорошего решения. Каллиграфия расширяет атрибут android:fontFamily чтобы добавить поддержку пользовательских шрифтов в папке вашего ресурса, например:

 <TextView android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="fonts/Roboto-Bold.ttf"/> 

Единственное, что вам нужно сделать, чтобы активировать его, – это привязать его к контексту действия, которое вы используете:

 @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(new CalligraphyContextWrapper(newBase)); } 

Вы также можете указать свой собственный атрибут для замены android:fontFamily

Он также работает в темах, включая AppTheme.

Если у вас есть только один шрифт, который вы хотели бы добавить, и вам нужно меньше писать код, вы можете создать выделенный TextView для своего конкретного шрифта. См. Код ниже.

 package com.yourpackage; import android.content.Context; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.TextView; public class FontTextView extends TextView { public static Typeface FONT_NAME; public FontTextView(Context context) { super(context); if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf"); this.setTypeface(FONT_NAME); } public FontTextView(Context context, AttributeSet attrs) { super(context, attrs); if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf"); this.setTypeface(FONT_NAME); } public FontTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if(FONT_NAME == null) FONT_NAME = Typeface.createFromAsset(context.getAssets(), "fonts/FontName.otf"); this.setTypeface(FONT_NAME); } } 

В main.xml теперь вы можете добавить свой текстовый вид следующим образом:

 <com.yourpackage.FontTextView android:id="@+id/tvTimer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" /> 

Использование DataBinding :

 @BindingAdapter({"bind:font"}) public static void setFont(TextView textView, String fontName){ textView.setTypeface(Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + fontName)); } 

В XML:

 <TextView app:font="@{`Source-Sans-Pro-Regular.ttf`}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> 

Файл шрифта должен находиться в assets/fonts/

Расширьте TextView и дайте ему настраиваемый атрибут или просто используйте атрибут android: tag, чтобы передать строку, какой шрифт вы хотите использовать. Вам нужно будет выбрать соглашение и придерживаться его, например, я поместил все мои шрифты в папку res / assets / fonts /, чтобы ваш класс TextView знал, где их найти. Затем в вашем конструкторе вы просто устанавливаете шрифт вручную после супервызов.

Исходный код – единственный способ использования пользовательских шрифтов.

Просто помните, что Android работает на устройствах с очень ограниченными ресурсами, а шрифты могут потребовать достаточного объема оперативной памяти. Встроенные Droid шрифты специально сделаны, и, если вы заметили, у вас много символов и украшений.

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

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

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

 <?xml version="1.0" encoding="utf-8"?> <font-family xmlns:android="http://schemas.android.com/apk/res/android"> <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/hey_regular" /> <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/hey_bababa" /> </font-family> 

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

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

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

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

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

У меня может быть простой ответ на вопрос без расширения TextView и реализации длинного кода.

Код:

  TextView tv = (TextView) findViewById(R.id.textview1); tv.setTypeface(Typeface.createFromAsset(getAssets(), "font.ttf")); 

Поместите файл пользовательского шрифта в папку с ресурсами, как обычно, и попробуйте это. Меня устраивает. Я просто не понимаю, почему Питер дал такой огромный код для этой простой вещи, или он дал свой ответ в старой версии.

Также может быть определено в xml без создания пользовательских классов

style.xml

 <style name="ionicons" parent="android:TextAppearance"> <!-- Custom Attr--> <item name="fontPath">fonts/ionicons.ttf</item> </style> 

activity_main.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/ionicons" android:text=""/> </LinearLayout> 

Быстрое замечание, потому что я всегда забывал, куда помещать шрифты, его шрифт должен быть внутри assets и эта папка находится на том же уровне, что и res и src , в моем случае его assets/fonts/ionicons.ttf

Обновлен Добавленный корневой макет, потому что для этого метода требуется xmlns:app="http://schemas.android.com/apk/res-auto" для работы

Обновление 2 Забыл о библиотеке, которую я установил до вызова каллиграфии

Ответ Питера является лучшим, но его можно улучшить, используя styles.xml от Android, чтобы настроить шрифты для всех текстовых просмотров в вашем приложении.

Мой код здесь

Вот учебник, в котором показано, как настроить пользовательский шрифт, например, @peter: http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

Он также учитывает потенциальные утечки памяти ala http://code.google.com/p/android/issues/detail?id=9904 . Также в учебнике приведен пример настройки пользовательского шрифта на кнопке.

Fontinator – это Android-библиотека, облегчающая использование пользовательских шрифтов. https://github.com/svendvd/Fontinator

Вы не можете расширять TextView для создания виджета или использовать его в макете виджетов: http://developer.android.com/guide/topics/appwidgets/index.html