4

В моем коде есть серьезная проблема, в которой я загружаю шрифт в свою папку assets\fonts\ из пользовательского класса TextView. Первая проблема заключается в том, что он сбой на 4.0 устройствах с исключением Caused by: java.lang.RuntimeException: native typeface cannot be made. Я использовал тот же самый процесс here с помощью метода:RuntimeException: собственный шрифт не может быть создан или утечка памяти для пользовательского шрифта загрузки TextView

public class MyTextView extends TextView { 

     public MyTextView(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
     } 

    public MyTextView(Context context, AttributeSet attrs) { 
      super(context, attrs); 
     } 

    public MyTextView(Context context) { 
      super(context); 
    } 


    public void setTypeface(Typeface tf, int style) { 
     if (style == Typeface.BOLD) { 
      super.setTypeface(Typeface.createFromAsset(
        getContext().getAssets(), "fonts/hirakakupronbold.ttf")); 
     } else if (style == Typeface.ITALIC) { 
      super.setTypeface(Typeface.createFromAsset(
        getContext().getAssets(), "fonts/hirakakupronitalic.ttf")); 
     } else { 
      super.setTypeface(Typeface.createFromAsset(
        getContext().getAssets(), "fonts/hirakakupron.ttf")); 
     } 
    } 
} 

Обратите внимание, что я использую расширение .ttf, и я обнаружил, что это вызывает RunTimeException. Поэтому я преобразовал соответствующие шрифты с расширениями .otf, и теперь он работает уже в 4.0 устройствах, но имеет утечки памяти на основе here. Есть обходные пути here, но я не знаю, как их использовать/называть. Любая помощь поможет, спасибо.

ответ

8

Хорошо, так что я, наконец, понял, что инстанцирование TypeFace объекта внутри класс TextView будет вызывать так много нагрузки каждый раз, когда будет создан тот же TextView. Это вызвало мое отставание приложения и привело к тому, что в конце концов было OutOfMemoryException. Так что я сделал, чтобы создать другой пользовательский класс TypeFace, который будет вызывать мои шрифты из активов так, чтобы он создавал класс TypeFace, а не из класса TextView.

Вот мой Гарнитуры класс:

public class TypeFaces { 

    private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>(); 

    public static Typeface getTypeFace(Context context, String assetPath) { 
     synchronized (cache) { 
      if (!cache.containsKey(assetPath)) { 
       try { 
        Typeface typeFace = Typeface.createFromAsset(
          context.getAssets(), assetPath); 
        cache.put(assetPath, typeFace); 
       } catch (Exception e) { 
        Log.e("TypeFaces", "Typeface not loaded."); 
        return null; 
       } 
      } 
      return cache.get(assetPath); 
     } 
    } 
} 

И пользовательский класс TextView:

public class TextViewHirakaku extends TextView { 

    public TextViewHirakaku(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public TextViewHirakaku(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public TextViewHirakaku(Context context) { 
     super(context); 
    } 

    public void setTypeface(Typeface tf, int style) { 
     if (style == Typeface.BOLD) { 
      super.setTypeface(TypeFaces.getTypeFace(getContext(), 
        "fonts/hirakakupronbold.ttf")); 
     } else if (style == Typeface.ITALIC) { 
      super.setTypeface(TypeFaces.getTypeFace(getContext(), 
        "fonts/hirakakupronitalic.ttf")); 
     } else { 
      super.setTypeface(TypeFaces.getTypeFace(getContext(), 
        "fonts/hirakakupron.ttf")); 
     } 
    } 
} 

Обратите внимание, что я в настоящее время называют getTypeFace метод из TypeFaces класса здесь.

1

Если вы расширяете этот вид с XML, то попробуйте использовать его таким образом ::

public class MyTextView extends TextView { 

    public MyTextView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(); 
    } 

public MyTextView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

public MyTextView(Context context) { 
     super(context); 
     init(); 
} 


public void init() { 
    Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/hirakakupronbold.ttf"); 
    setTypeface(tf); 

} 

}

Сво работает нормально для меня. Сделать отдельный класс, расширяющий TextView для каждой гарнитуру style.to Чтобы применить его, заменить «TextView» с «com.yourpackage.MyTextView»

С уважением,

6

Если у вас возникла эта проблема в Android Studio, тогда поместите свои ресурсы в основной каталог вместо того, чтобы помещать его в каталог res.

Также в названии шрифта используются строчные буквы и подчеркивания, например. my_font.ttf

Это работало как шарм для меня

+0

большое спасибо! это помогло мне! – Ilario

0

В моем случае префикс XML пространство имен, которое я использую для моего пользовательского представления (Costum) не был установлен правильно:

xmlns:costum="http://schemas.android.com/apk/tools" 

Все, что я должен был сделать это, чтобы изменить его

xmlns:costum="http://schemas.android.com/apk/res-auto" 

& он работал.