我应用了一个自定义字体TextView,但它似乎没有改变字体。
这是我的代码:
Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(myTypeface);
谁能帮我摆脱这个问题?
我应用了一个自定义字体TextView,但它似乎没有改变字体。
这是我的代码:
Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(myTypeface);
谁能帮我摆脱这个问题?
当前回答
由于我对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帖子中粘来的,为活动和片段提供了helper方法:
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;
}
}
其他回答
如果你把字体放在正确的地方,字体文件本身没有错误,你的代码应该像那样工作,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 8.0 (API级别26)引入了一个新特性,XML字体。 只要在运行Android 4.1 (API级别16)或更高的设备上使用XML字体功能,使用支持库26。
请看这个链接
旧的答案
有两种方法来定制字体:
! !自定义字体 资产/字体/ iran_sans.ttf
方法一: 反射字体。class |||最好的方式
在类extends Application中调用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;
}
}
在尝试了这篇文章中描述的大多数解决方案后,我偶然发现了Calligraphy (https://github.com/chrisjenx/Calligraphy) - Christopher Jenkins的一个库,可以让你轻松地向应用程序添加自定义字体。与这里建议的方法相比,他的库的优点是:
你不必引入自己的重载TextView组件,你使用内置的TextView 您可以使用gradle轻松地包含该库 图书馆不限制你的字体选择;您只需将您喜欢的添加到资产目录 你不仅得到自定义文本视图-所有其他基于文本的Android组件也将显示使用您的自定义字体。
对于android中的自定义字体,在assets文件夹中创建一个文件夹,命名为“Fonts”,将您想要的Fonts .ttf或.otf文件放在其中。
如果你扩展UIBaseFragment:
Typeface font = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Arial.ttf");
tv.setTypeface(font);
else if扩展活动:
Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/Arial.ttf");
tv.setTypeface(font);