Пользовательские шрифты и макеты XML (Android) - PullRequest
173 голосов
/ 04 марта 2010

Я пытаюсь определить макет GUI, используя файлы XML в Android. Насколько я могу судить, нет никакого способа указать, что ваши виджеты должны использовать пользовательский шрифт (например, тот, который вы поместили в assets / font /) в XML-файлах, и вы можете использовать только системные шрифты.

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

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

Ответы [ 18 ]

2 голосов
/ 31 октября 2015

Также может быть определен в XML без создания пользовательских классов

style.xml

<style name="ionicons" parent="android:TextAppearance">
    <!-- Custom Attr-->
    <item name="fontPath">fonts/ionicons.ttf</item>
</style>

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/ionicons"
        android:text=""/>
</LinearLayout>

Небольшое примечание, потому что я просто всегда забывал, куда помещать шрифты, его шрифт должен быть внутри assets, и эта папка находится на том же уровне, что и res и src, в моем дело его assets/fonts/ionicons.ttf

Обновлено Добавлена ​​корневая раскладка, поскольку для работы этого метода требуется xmlns:app="http://schemas.android.com/apk/res-auto"

Обновление 2 Забыл о библиотеке, которую я установил раньше, под названием Каллиграфия

1 голос
/ 30 августа 2017

Существует два способа настройки шрифтов:

!!! мой пользовательский шрифт в assets / fonts / iran_sans.ttf

Путь 1: Refrection Typeface.class ||| лучший способ

вызов 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;
    }

}
1 голос
/ 05 сентября 2012

Ответ Питера - лучший, но его можно улучшить с помощью styles.xml из Android, чтобы настроить шрифты для всех текстовых представлений в вашем приложении.

Мой код здесь

0 голосов
/ 09 февраля 2019

Может быть полезно знать, что начиная с Android 8.0 (уровень API 26) вы можете использовать собственный шрифт в XML .

Вы можете применить собственный шрифт ко всему приложению следующим образом.

  1. Поместите шрифт в папку res/font.

  2. В res/values/styles.xml используйте его в теме приложения. <style name="AppTheme" parent="{whatever you like}"> <item name="android:fontFamily">@font/myfont</item> </style>

0 голосов
/ 06 февраля 2018

Вы можете легко создать пользовательский текстовый класс: -

Итак, что вам нужно сделать в первую очередь, сделать класс Custom textview, который был расширен с AppCompatTextView.

public class CustomTextView extends AppCompatTextView {
    private int mFont = FontUtils.FONTS_NORMAL;
    boolean fontApplied;

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

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

    public CustomTextView(Context context) {
        super(context);
        init(null, context);
    }

    protected void init(AttributeSet attrs, Context cxt) {
        if (!fontApplied) {
            if (attrs != null) {
                mFont = attrs.getAttributeIntValue(
                        "http://schemas.android.com/apk/res-auto", "Lato-Regular.ttf",
                        -1);
            }
            Typeface typeface = getTypeface();
            int typefaceStyle = Typeface.NORMAL;
            if (typeface != null) {
                typefaceStyle = typeface.getStyle();
            }
            if (mFont > FontUtils.FONTS) {
                typefaceStyle = mFont;
            }
            FontUtils.applyFont(this, typefaceStyle);
            fontApplied = true;
        }
    }
}

Теперь каждый раз при вызове Пользовательского текстового представления мы получим значение int из атрибута int fontValue = attrs.getAttributeIntValue("http://schemas.android.com/apk/res-auto","Lato-Regular.ttf",-1).

Или

Мы также можем получить getTypeface () из представления, которое мы установили в нашем xml (android:textStyle="bold|normal|italic"). Так что делай, что хочешь.

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

public class FontUtils {

    public static final int FONTS = 1;
    public static final int FONTS_NORMAL = 2;
    public static final int FONTS_BOLD = 3;
    public static final int FONTS_BOLD1 = 4;

    private static Map<String, Typeface> TYPEFACE = new HashMap<String, Typeface>();

    static Typeface getFonts(Context context, String name) {
        Typeface typeface = TYPEFACE.get(name);
        if (typeface == null) {
            typeface = Typeface.createFromAsset(context.getAssets(), name);
            TYPEFACE.put(name, typeface);
        }
        return typeface;
    }

    public static void applyFont(TextView tv, int typefaceStyle) {

        Context cxt = tv.getContext();
        Typeface typeface;

        if(typefaceStyle == Typeface.BOLD_ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }else if (typefaceStyle == Typeface.BOLD || typefaceStyle == SD_FONTS_BOLD|| typefaceStyle == FONTS_BOLD1) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-SemiBold.ttf");
        } else if (typefaceStyle == Typeface.ITALIC) {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Thin.ttf");
        } else {
            typeface = FontUtils.getFonts(cxt, "FaktPro-Normal.ttf");
        }
        if (typeface != null) {
            tv.setTypeface(typeface);
        }
    }
}
0 голосов
/ 16 марта 2011

Вы не можете расширить TextView, чтобы создать виджет или использовать его в макете виджета: http://developer.android.com/guide/topics/appwidgets/index.html

0 голосов
/ 27 февраля 2012

Вот учебник, который показывает вам, как настроить собственный шрифт, как описано @peter: http://responsiveandroid.com/2012/03/15/custom-fonts-in-android-widgets.html

он также учитывает потенциальные утечки памяти ala http://code.google.com/p/android/issues/detail?id=9904. Также в руководстве приведен пример установки пользовательского шрифта для кнопки.

0 голосов
/ 30 ноября 2014

Fontinator - это Android-библиотека, упрощающая использование пользовательских шрифтов.https://github.com/svendvd/Fontinator

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...