Intereting Posts
Как читать XML-файл в android Andoird: Пользовательский переключатель: как сделать большой палец более 50% дорожки без использования изображений Почему мой pom не выполняется правильно при использовании Android Studio / IntelliJ? Перенос с GCM 2.0 на GCM 3.0 API-интерфейс InstanceID Как проверить, установлено ли мое приложение по умолчанию или нет в android? Android: NoClassDefFound Android TabLayout больше не отображает содержимое, как только фрагмент переключается Ошибка: О, о! ENOENT, нет такого файла или каталога '<meteor-app> /. Meteor / local / cordova-build / platform / android / local.properties' Не удалось поймать событие кнопки андроида Невозможно ссылаться на тему темы Holo из value-v11 / themes.xml Firebase Crash производит ANR во время запуска Как сделать слайд, чтобы разблокировать кнопку в android Остановить AppBarLayout прокрутку экрана, когда NestedScrollView пуст SwipeRefreshLayout Получил событие ACTION_MOVE, но не имеет активного идентификатора указателя Как изменить образ homeAsUpIndicator в теме по умолчанию Theme.Holo.Light

Использование пользовательского шрифта в android TextView с помощью xml

Я добавил файл пользовательского шрифта в папку my assets / fonts. Как использовать его из моего XML?

Я могу использовать его из кода следующим образом:

TextView text = (TextView) findViewById(R.id.textview03); Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Molot.otf"); text.setTypeface(tf); 

Не могу ли я сделать это из XML, используя атрибут android:typeface="/fonts/Molot.otf" ?

Solutions Collecting From Web of "Использование пользовательского шрифта в android TextView с помощью xml"

Короткий ответ: Нет. Android не имеет встроенной поддержки для применения пользовательских шрифтов к текстовым виджетам через XML.

Тем не менее, есть обходной путь, который не так сложно реализовать.

Первый

Вам нужно будет определить свой собственный стиль. В папке / res / values ​​откройте / создайте файл attrs.xml и добавьте объект, подобный объявлению:

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

второй

Предполагая, что вы хотите использовать этот виджет часто, вы должны настроить простой кеш для загружаемых объектов Typeface , так как загрузка их из памяти «на лету» может занять некоторое время. Что-то вроде:

 public class FontManager { private static FontManager instance; private AssetManager mgr; private Map<String, Typeface> fonts; private FontManager(AssetManager _mgr) { mgr = _mgr; fonts = new HashMap<String, Typeface>(); } public static void init(AssetManager mgr) { instance = new FontManager(mgr); } public static FontManager getInstance() { return instance; } public Typeface getFont(String asset) { if (fonts.containsKey(asset)) return fonts.get(asset); Typeface font = null; try { font = Typeface.createFromAsset(mgr, asset); fonts.put(asset, font); } catch (Exception e) { } if (font == null) { try { String fixedAsset = fixAssetFilename(asset); font = Typeface.createFromAsset(mgr, fixedAsset); fonts.put(asset, font); fonts.put(fixedAsset, font); } catch (Exception e) { } } return font; } private String fixAssetFilename(String asset) { // Empty font filename? // Just return it. We can't help. if (StringUtils.isEmpty(asset)) return asset; // Make sure that the font ends in '.ttf' or '.ttc' if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc"))) asset = String.format("%s.ttf", asset); return asset; } } 

Это позволит вам использовать расширения .ttc, но не проверено.

В третьих

Создайте новый класс, который подклассы TextView . В этом конкретном примере учитывается определенный шрифт XML ( bold , italic и т. Д.) И применяют его к шрифту (при условии, что вы используете файл .ttc).

 /** * TextView subclass which allows the user to define a truetype font file to use as the view's typeface. */ public class FontText extends TextView { public FontText(Context context) { this(context, null); } public FontText(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FontText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if (isInEditMode()) return; TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText); if (ta != null) { String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset); if (!StringUtils.isEmpty(fontAsset)) { Typeface tf = FontManager.getInstance().getFont(fontAsset); int style = Typeface.NORMAL; float size = getTextSize(); if (getTypeface() != null) style = getTypeface().getStyle(); if (tf != null) setTypeface(tf, style); else Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset)); } } } } 

в заключение

Замените экземпляры TextView в вашем XML с полным именем класса. Объявите свое собственное пространство имен так же, как и пространство имен Android. Обратите внимание, что «typefaceAsset» должен указывать на файл .ttf или .ttc, содержащийся в вашем каталоге / assets.

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.FontText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="This is a custom font text" custom:typefaceAsset="fonts/AvenirNext-Regular.ttf"/> </RelativeLayout> 

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

 public class TextViewWithFont extends TextView { public TextViewWithFont(Context context, AttributeSet attrs) { super(context, attrs); this.setTypeface(MainActivity.typeface); } public TextViewWithFont(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.setTypeface(MainActivity.typeface); } public TextViewWithFont(Context context) { super(context); this.setTypeface(MainActivity.typeface); } } 

Activity реализует LayoutInflater.Factory2, который обеспечивает обратные вызовы для каждого созданного View. Можно создать стиль TextView с пользовательским атрибутом fontFamily, загружать шрифты по требованию и автоматически вызывать setTypeface при создании экземпляров текста.

К сожалению, из-за архитектурных взаимоотношений экземпляров Inflater по отношению к действиям и Windows самый простой подход заключается в кэшировании загруженных шрифтов на уровне приложения.

База кода примера находится здесь:

https://github.com/leok7v/android-textview-custom-fonts

  <style name="Baroque" parent="@android:style/TextAppearance.Medium"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textColor">#F2BAD0</item> <item name="android:textSize">14pt</item> <item name="fontFamily">baroque_script</item> </style> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res/custom.fonts" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView style="@style/Baroque" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/sample_text" /> 

Приводит к

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

Создайте свой собственный TextView в соответствии с шрифтом, который вы хотите использовать. В этом классе я использую статическое поле mTypeface для кэширования Typeface (для лучшей производительности)

 public class HeliVnTextView extends TextView { /* * Caches typefaces based on their file path and name, so that they don't have to be created every time when they are referenced. */ private static Typeface mTypeface; public HeliVnTextView(final Context context) { this(context, null); } public HeliVnTextView(final Context context, final AttributeSet attrs) { this(context, attrs, 0); } public HeliVnTextView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); if (mTypeface == null) { mTypeface = Typeface.createFromAsset(context.getAssets(), "HelveticaiDesignVnLt.ttf"); } setTypeface(mTypeface); } } 

В файле xml:

 <java.example.HeliVnTextView android:id="@+id/textView1" android:layout_width="0dp" ... /> 

В классе java:

 HeliVnTextView title = new HeliVnTextView(getActivity()); title.setText(issue.getName()); 

Не очень хорошая идея использовать пользовательские шрифты в xml из-за этого факта, то есть вы должны делать это программно, чтобы избежать утечки памяти!

UPDATE: https://github.com/chrisjenx/Calligraphy представляется превосходным решением.


Может быть, вы можете использовать рефлексию для ввода / взлома шрифта в статический список доступных шрифтов, когда ваше приложение создано? Меня интересует обратная связь от других, если это действительно очень плохая идея или если это отличное решение – похоже, это будет одна из тех крайностей …

Я смог ввести свой собственный шрифт в список системных шрифтов с моим собственным именем семейства шрифтов, а затем указать, что собственное семейство имен шрифтов («кисть-скрипт») как значение android: FontFamily на стандартном TextView работало на моем LG G4 работает под управлением Android 6.0.

 public class MyApplication extends android.app.Application { @Override public void onCreate() { super.onCreate(); Typeface font = Typeface.createFromAsset(this.getResources().getAssets(),"fonts/brush-script.ttf"); injectTypeface("brush-script", font); } private boolean injectTypeface(String fontFamily, Typeface typeface) { try { Field field = Typeface.class.getDeclaredField("sSystemFontMap"); field.setAccessible(true); Object fieldValue = field.get(null); Map<String, Typeface> map = (Map<String, Typeface>) fieldValue; map.put(fontFamily, typeface); return true; } catch (Exception e) { Log.e("Font-Injection", "Failed to inject typeface.", e); } return false; } } 

В моем макете

 <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Fancy Text" android:fontFamily="brush-script"/> 

Вместо xmlns: custom = "schemas.android.com/tools"; Вы должны использовать: xmlns: custom = "schemas.android.com/apk/res-auto"; Чтобы использовать атрибуты стиля. Я сделал это изменение, и он работает сейчас.

Создайте папку fonts в активах и добавьте все необходимые шрифты.

 public class CustomTextView extends TextView { private static final String TAG = "TextView"; public CustomTextView(Context context) { super(context); } public CustomTextView(Context context, AttributeSet attrs) { super(context, attrs); setCustomFont(context, attrs); } public CustomTextView(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.CustomTextView); String customFont = a.getString(R.styleable.CustomTextView_customFont); setCustomFont(ctx, customFont); a.recycle(); } public boolean setCustomFont(Context ctx, String fontName) { Typeface typeface = null; try { if(fontName == null){ fontName = Constants.DEFAULT_FONT_NAME; } typeface = Typeface.createFromAsset(ctx.getAssets(), "fonts/" + fontName); } catch (Exception e) { Log.e(TAG, "Unable to load typeface: "+e.getMessage()); return false; } setTypeface(typeface); return true; } } 

И добавить объявление в attrs.xml

 <declare-styleable name="CustomTextView"> <attr name="customFont" format="string"/> </declare-styleable> 

А затем добавить свой customFont, как

 app:customFont="arial.ttf"