Android – 使用自定义字体

我将自定义字体应用于TextView ,但似乎没有改变字体。

这是我的代码:

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

任何人都可以请我摆脱这个问题?

在Mobiletuts +上有非常好的Android教程。 快速提示:自定义Android字体

编辑:现在testing它。 这是解决scheme。 您可以使用称为字体的子文件夹,但它必须在assets文件夹而不是res文件夹。 所以

资产/字体

还要确保字体结尾的意思是字体文件本身的结尾都是小写的。 换句话说,它不应该是myFont.TTFmyfont.ttf 这种方式必须小写

在尝试了本主题中介绍的大部分解决scheme之后,我意外地发现了书法( https://github.com/chrisjenx/Calligraphy ) – Christopher Jenkins的一个库,可以让您轻松地将自定义字体添加到您的应用程序中。 他的lib比较这里提出的方法的优点是:

  1. 您不必引入自己的被覆盖的TextView组件,就可以使用内置的TextView
  2. 你可以很容易地使用gradle包含库
  3. 图书馆不限制你select的字体; 您只需将您的首选项添加到资产目录
  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> 

我已经成功地使用过。 我们的实现之间唯一的区别是我没有在资产中使用子文件夹。 不知道这是否会改变什么,但。

假如你把字体放在正确的位置,字体文件本身没有错误,你的代码应该像这样工作,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> 

我为此专门创build了一些工具。 从GitHub参考这个项目 ,或者看看这个博客文章来解释整个事情。

对于Android中的自定义字体在资产文件夹内创build一个文件夹命名为“字体”将您所需的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); 

最好的方式做到这一点从Android O的预览版本是这样的:

它只适用于Android Studio-2.4或更高版本

  1. 右键单击res文件夹并转到新build> Android资源目录 。 新的
    资源目录窗口出现。
  2. 在资源types列表中select字体 ,然后单击确定。
  3. 将字体文件添加到字体文件夹中 。下面的文件夹结构生成R.font.dancing_scriptR.font.la_laR.font.ba_ba
  4. 双击字体文件以在编辑器中预览文件的字体。

接下来我们必须创build一个字体家族:

  1. 右键单击字体文件夹并转到新build>字体资源文件 。 出现“新build资源文件”窗口。
  2. input文件名称,然后单击确定 。 新的字体资源XML在编辑器中打开。
  3. 在字体标签元素中包含每个字体文件,样式和重量属性。 以下XML说明了在字体资源XML中添加与字体相关的属性:

将字体添加到TextView中:

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

从文档

与字体一起使用

所有的步骤都是正确的。

您可以在https://github.com/neopixl/PixlUI使用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" /> 

由于我对所有提出的解决scheme都不满意,所以我提出了我的想法。 它基于一个带有标签的小技巧(即,你不能在代码中使用标签),我把字体path放在那里。 所以在定义视图时,你可以这样做:

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

调用super和调用setContentView() 之后,确保将上面的代码粘贴到onCreate()中。 这个小细节让我挂了一会儿。

我有同样的问题,TTF没有出现。 我改变了字体文件,并使用相同的代码工作。

如果您想要从networking加载字体或轻松地设置字体,可以使用:

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

不幸的是没有好的解决scheme。

我已经看到了许多关于使用自定义TextView的文章,但是他们忘记了它不仅仅是可以实现字体的文本视图,还有在开发人员无法访问的其他视图中隐藏的文本视图。 我甚至不会在Spannable开始

您可以使用外部字体实用程序,如:

书法字体工具

但是,这在创build应用程序的每一个视图上循环,甚至这个工具忽略了一些视图(ViewPager呈现正常的字体),那么你有问题,当谷歌更新他们的构build工具,这有时会崩溃,因为它需要针对不推荐使用的属性。 它使用Java的reflection也有点慢。

Google真的需要解决这个问题。 Android需要更好的字体支持。 如果你看看从iOS的解决scheme,他们实际上有100的字体内置可供select。 想要一个自定义字体? 简单地放一个TFF,它是可用的..

现在只限于Google为我们提供的产品,这个产品非常有限,但幸运的是手机已经过优化。

您可以使用简单易用的EasyFonts第三方库来为您的TextView设置各种自定义字体。 通过使用这个库,您不必担心下载并将字体添加到assets / fonts文件夹中。 还有关于字体对象的创build。

代替

 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
  • Droid Serif
  • 机器人机器人
  • 自由
  • 有趣的提升者
  • Android国家
  • 绿色鳄梨
  • 承认

我是这个图书馆的作者。

API 26的正确方法在官方文档中描述:

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

这涉及将ttf文件放置在res / font文件夹中并创build一个字体族文件。

那么,七年后,你可以更改整个应用程序textView或你想要的东西很容易通过使用android.support库26 + +。

例如:

创build你的字体软件包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果冻豆这是一个广泛的范围。

有两种方法可以自定义字体:

! 我的资产/字体/ 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; } }