我有一个自定义扩展TextView
我在我的应用程序中使用自定义字体,但由于某种原因,我一直得到一个运行时异常,程序无法找到有问题的字体。
我正在使用的目录格式为main > assets > fonts > Portrait-Light.ttf
我到处寻找一个解决方案,但他们似乎都在SO上找到相同的答案。
CustomFontTextView.java:
public class CustomFontTextView extends TextView {
public CustomFontTextView(Context context) {
super(context);
applyCustomFont(context);
}
public CustomFontTextView(Context context, AttributeSet attrs) {
super(context, attrs);
applyCustomFont(context);
}
public CustomFontTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
applyCustomFont(context);
}
private void applyCustomFont(Context context) {
Log.e("it gets here", "custom font");
Typeface customFont = FontCache.getTypeface("Roboto-Italic.ttf", context);
setTypeface(customFont);
}
}
FontCache.java
class FontCache {
private static HashMap<String, Typeface> fontCache = new HashMap<>();
static Typeface getTypeface(String fontname, Context context) {
Typeface typeface = fontCache.get(fontname);
if (typeface == null) {
try {
typeface = Typeface.createFromAsset(context.getAssets(), "fonts/" + fontname);
} catch (Exception e) {
Log.e("failed", e.getMessage());
}
fontCache.put(fontname, typeface);
}
return typeface;
}
}
XML:
<icn.premierandroid.misc.CustomFontTextView
android:id="@+id/switch_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="14sp"
android:textColor="@color/colorPrimary"
android:gravity="center_horizontal"
android:text="@string/are_you_over_18_years_old"/>
我尝试过不同的格式,例如.otf
和不同的字体,例如Roboto-Italic.ttf
和另一个来自dafont.com的随机字体Sunset-Clouds.ttf
,但我仍然收到错误消息,到底是怎么回事?这应该是有效的。我甚至更新了所有插件,如Gradle,Grade-Wrapper发行版和Android gradle插件,以防万一。
我也尝试过单一的方式:
AssetManager am = context. getApplicationContext(). getAssets();
Typeface font = Typeface.createFromAsset(
am, String.format(Locale.US, "fonts/%s", "portrait-light.ttf"));
我错过了什么吗?
更新:
删除捕获会显示此堆栈跟踪。
处理:icn.premierandroid,PID:3829 java.lang.RuntimeException:无法启动活动ComponentInfo {icn.premierandroid / icn.premierandroid.RegisterActivity}: android.view.InflateException:二进制XML文件行#100:错误 膨胀类icn.premierandroid.misc.CustomFontTextView 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702) 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767) .....
引起:android.view.InflateException:二进制XML文件行#100: 错误膨胀类icn.premierandroid.misc.CustomFontTextView 在android.view.LayoutInflater.createView(LayoutInflater.java:640) 在android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750) 在android.view.LayoutInflater.rInflate(LayoutInflater.java:813)
.....
引起:java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 在android.view.LayoutInflater.createView(LayoutInflater.java:614)
...
引起:java.lang.RuntimeException:找不到字体资源 字体/ GleegooRegular.ttf 在android.graphics.Typeface.createFromAsset(Typeface.java:272) at icn.premierandroid.misc.FontCache.getTypeface(FontCache.java:21) at icn.premierandroid.misc.CustomFontTextView.applyCustomFont(CustomFontTextView.java:28) at icn.premierandroid.misc.CustomFontTextView。(CustomFontTextView.java:18) at java.lang.reflect.Constructor.newInstance(Native Method)
.....
更新2:
好的,所以有一个奇怪的解决办法。显然,当您将assets
文件夹直接添加到main
内的app/src/main
文件夹中时,android studio不喜欢它。您需要先将其添加到app/src/main/res
文件夹中,然后将其移至main
文件夹。不知道为什么会这样,但它解决了我的问题。
答案 0 :(得分:1)
我们根据需要写了这个课程。它允许使用属性设置我们的自定义字体,如下所示:
app:customFont="Roboto-Medium.ttf"
希望你觉得它很有用:
public class TextViewFonted extends TextView {
private static final String TAG = "TextViewFonted";
public TextViewFonted(Context context) {
super(context);
}
public TextViewFonted(Context context, AttributeSet attrs) {
super(context, attrs);
setCustomFont(context, attrs);
}
public TextViewFonted(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.TextViewFonted);
String customFont = a.getString(R.styleable.TextViewFonted_customFont);
if (customFont == null) customFont = "Roboto-Regular.ttf";
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);
return false;
}
setTypeface(tf);
setLineSpacing(getTextSize() * 0.3f, 0.75f);
return true;
}
}
为了能够使用此自定义属性,您应该添加到 attrs.xml 下一个块(因此 R.styleable.TextViewFonted_customFont 将起作用):
<declare-styleable name="TextViewFonted">
<attr name="customFont" format="string"/>
</declare-styleable>
在我们的示例中,我们将字体放在 assets 文件夹的根目录中,但您可以在方法 setCustomFont()
中更改此行为<强>更新强>
要添加此字体,例如,我们使用
app:customFont="Comfortaa-Bold.ttf"
答案 1 :(得分:1)
我认为真正的问题是您尚未配置资产文件夹。如果你有,它在项目视图中看起来像这样:
或者在Android视图中这样:
所以你应该在Studio中将此文件夹添加为assets文件夹: 单击项目结构窗口(或按Alt + 1),然后按Alt + Insert并选择Folder / Assets Folder。然后把你的字体放在那里。
从OP更新:
好的,所以有一个奇怪的解决办法。当你将assets文件夹直接添加到app / src / main中的主文件夹时,显然android studio不喜欢它。您需要先将其添加到app / src / main / res文件夹中,然后将其移动到主文件夹。不知道为什么会这样,但它解决了我的问题。
答案 2 :(得分:0)
试试这个......
put .ttf fonts in app > assets > fonts > Roboto-Italic.ttf
然后在onCreate方法中,
Typeface Roboto = Typeface.createFromAsset(getAssets(),
"fonts/Roboto-Italic.ttf");
并在textview等中设置字体
textview.setTypeface(Roboto);