Пользовательские шрифты и пользовательский текст на Android

Из приложения, которое мне нужно разработать, я получил специальный шрифт, который имеет много файлов, таких как FontName-Regular, FontName-Bold, FontName-it. Мне нужно использовать его во всех текстовых комментариях в приложении. Сначала я подумал, что это непростая задача. Посмотрите на SO и найдите очень приятный поток: здесь

Итак, сначала мне понравилось:

public static void overrideFonts(final Context context, final View v) {
    try {
        if (v instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) v;
            for (int i = 0; i < vg.getChildCount(); i++) {
                View child = vg.getChildAt(i);
                overrideFonts(context, child);
            }
        } else if (v instanceof TextView) {
            ((TextView)v).setTypeface(FONT_REGULAR);
        }
    } catch (Exception e) {
        e.printStackTrace();
        // ignore
    }
}

И вызвал этот метод во время onCreate в моей деятельности. Каждый textView в моем приложении показывал этот шрифт и мальчика, был ли я счастлив, что так легко ушел. Пока я не добрался до экрана, где для некоторых текстовых просмотров требуется Жирный как Style (android:textStyle="bold"). Затем я понял, что это решение не дает мне возможности загрузить Font-Bold.ttf из активов.

Затем он посмотрел дальше и увидел хорошую пользовательскую реализацию TextView в том же SO-вопросе:

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(), "font/chiller.ttf");
        setTypeface(tf ,1);

    }
    }

Это выглядит еще лучше. Мой вопрос: как я могу обнаружить на init(), если мой элемент управления имеет стиль, установленный на "Жирный" или "нет", поэтому я могу назначить запрашиваемый TypeFace?

Спасибо за ваше время.

LE. Следуя приведенному ниже примеру, я обновил свой класс следующим образом:

public class MyTextView extends TextView {

    Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), Constants.FONT_REGULAR);
    Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(),  Constants.FONT_BOLD);

    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(boldTypeface/*, -1*/);
        } else {
            super.setTypeface(normalTypeface/*, -1*/);
        }
    }
}

Ну, если я отлаживаю, приложение входит в setTypeFace, и похоже, что оно имеет жирный шрифт, но на моем макете я не вижу никаких изменений, а не полужирного. Независимо от того, какой шрифт я использую, в моем TextView никаких изменений не происходит и отображается с помощью шрифта android по умолчанию. Интересно, почему?

Я суммировал все на блоге здесь, в моем блоге, возможно, это поможет кому-то.

Ответ 1

Конструктор TextView вызывает setTypeface(Typeface tf, int style) с параметром style, извлеченным из атрибута XML android:textStyle. Итак, если вы хотите перехватить этот вызов, чтобы заставить свой собственный шрифт, вы можете переопределить этот метод следующим образом:

public void setTypeface(Typeface tf, int style) {
    Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/your_normal_font.ttf");
    Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/your_bold_font.ttf");

    if (style == Typeface.BOLD) {
        super.setTypeface(boldTypeface/*, -1*/);
    } else {
        super.setTypeface(normalTypeface/*, -1*/);
    }
}

Ответ 2

Вы можете использовать мой CustomTextView, который позволяет указать имя файла шрифта в папке assets:

https://github.com/mafshin/CustomTextView

и использование очень просто:

<com.my.app.CustomTextView
        xmlns:custom="http://schemas.android.com/apk/res/com.my.app"            
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test text"
        android:id="@+id/testcustomview" 

        custom:fontAssetName="Politica XT.otf"
        />

Ответ 3

Я думаю, что лучше создать свой собственный пакет для пользовательских шрифтов и импортировать их в свой проект, чтобы вы могли использовать их позже в будущем

  package com.codeslips.utilities;  

  import android.content.Context; 
  import android.graphics.Typeface;
  import android.util.AttributeSet;
  import android.widget.TextView;  

  public class CustomTextView extends TextView {  

          public CustomTextView(Context context)
               { super(context); setFont(); }  

          public CustomTextView(Context context,AttributeSet set)
             { super(context,set); setFont(); } 

          public CustomTextView(Context context,AttributeSet set,int defaultStyle) 
             { super(context,set,defaultStyle); setFont(); } 

          private void setFont() { 

           Typeface typeface=Typeface.createFromAsset(getContext().getAssets(),"fonts/your-font.ttf"); 
           setTypeface(typeface); //function used to set font

             }  
          }

Теперь используйте вышеприведенный класс в вашем XML файле, чтобы иметь свой собственный шрифт

    <com.codeslips.utilities.CustomTextView   
       android:layout_width="wrap_content" 
       android:layout_height="match_parent"
       android:text="Upload Image" 
       android:paddingTop="10sp"
       android:textSize="14sp"
       android:layout_weight="0.7"
       android:textColor="@android:color/white"/>