Runtime Exception: Font not found for every font i've tried - Android

只愿长相守 提交于 2019-12-24 08:18:57

问题


I have a custom extended TextView I am using for custom fonts within my application, but for some reason I keep getting a run-time exception where the program can't find the font in question.

The format of the directory I'm using is main > assets > fonts > Portrait-Light.ttf

I've looked everywhere for a solution but they all seem to be rounding to the same answers on 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"/>

I have tried this with different formats such as .otf and with different fonts such as Roboto-Italic.ttf and another random one from dafont.com called Sunset-Clouds.ttf but still i get the error message, what is going on? this should be working. I've even updated all plugins such as Gradle, Grade-Wrapper distribution and Android gradle plugin just in case.

I have also tried the single way of doing it:

    AssetManager am = context. getApplicationContext(). getAssets();
    Typeface font = Typeface.createFromAsset(
    am, String.format(Locale.US, "fonts/%s", "portrait-light.ttf"));

Am i missing something?

Update:

Removal of the catch reveals this stacktrace.

Process: icn.premierandroid, PID: 3829 java.lang.RuntimeException: Unable to start activity ComponentInfo{icn.premierandroid/icn.premierandroid.RegisterActivity}: android.view.InflateException: Binary XML file line #100: Error inflating class icn.premierandroid.misc.CustomFontTextView at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767) .....

Caused by: android.view.InflateException: Binary XML file line #100: Error inflating class icn.premierandroid.misc.CustomFontTextView at android.view.LayoutInflater.createView(LayoutInflater.java:640) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750) at android.view.LayoutInflater.rInflate(LayoutInflater.java:813)

.....

Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:288) at android.view.LayoutInflater.createView(LayoutInflater.java:614)

....

Caused by: java.lang.RuntimeException: Font asset not found fonts/GleegooRegular.ttf at 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) 

.....

UPDATE 2:

Okay, so there is a weird work-around for this. Apparently android studio doesn't like it when you add the assets folder straight into the main folder inside app/src/main. You need to add it into the app/src/main/res folder first and then move it to the main folder. Don't have a clue why it's like this but it solved my problem.


回答1:


I think the real problem is that you haven't configured your assets folder. If you had, it would look like this in Project view:

Or like this in Android view:

So you should simply add this folder as assets folder in Studio: Click on your project structure window (or press Alt+1), then press Alt + Insert and select Folder/Assets Folder. Then put your fonts there.

Update from OP:

Okay, so there is a weird work-around for this. Apparently android studio doesn't like it when you add the assets folder straight into the main folder inside app/src/main. You need to add it into the app/src/main/res folder first and then move it to the main folder. Don't have a clue why it's like this but it solved my problem.




回答2:


We wrote this class for our needs. It allows to set our custom fonts using attribute, like this:

app:customFont="Roboto-Medium.ttf"

Hope you find it useful:

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

And to be able to use this custom attribute, you should add to your attrs.xml next block (so R.styleable.TextViewFonted_customFont will work):

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

In our case, we put fonts in the root of assets folder, but you could change this behavior in method setCustomFont()

Update

To add this font, for example, we use

app:customFont="Comfortaa-Bold.ttf"



回答3:


Try this....

put .ttf fonts in app > assets > fonts > Roboto-Italic.ttf

And then in onCreate method,

Typeface Roboto = Typeface.createFromAsset(getAssets(),
            "fonts/Roboto-Italic.ttf");

and set font in textview,etc

textview.setTypeface(Roboto);


来源:https://stackoverflow.com/questions/40587698/runtime-exception-font-not-found-for-every-font-ive-tried-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!