Как добавить локаль (со страной) в ресурсы шрифтов (библиотека поддержки v26)?


Google опубликовал официальную обработку ресурсов шрифтов с момента выхода библиотеки поддержки v26: https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

Однако, похоже, я не могу добавить классификатор страны для папки ресурсов шрифта.

У меня есть приложение, которое имеет 3 языка: английский, традиционный китайский и упрощенный китайский.

И я попытался назвать свою папку шрифтов под res этим путь:
font
font-zh
font-zh_CN
(Я также пытался font-zh-CN)

(обратите внимание, что zh - это язык, а CN - страна. С некоторым дополнительным контекстом для вашей информации - в Китае мы все используем "китайский", но есть упрощенный китайский и традиционный китайский; кроме того, Гонконг и Тайвань используют традиционный китайский, но способ их использования немного отличается. Самое главное, что шрифты имеют отдельные файлы для традиционного китайского и упрощенного китайского, из-за дело в том, что они совершенно разные по своей форме.)

Но я не могу построить проект. Android Studio постоянно говорит мне, что font-zh_CN (или font-zh-CN) - это недопустимое имя каталога ресурсов.

Это не происходит для моей папки values-zh_CN (и не values-zh-CN).

Вопрос:

Как вы используете различные шрифты для того же языка, но другой страны , используя новый официальный метод начиная с API 26?

2 7

2 ответа:

Шаблон для имен папок ресурсов определен в таблице 2 здесь: https://developer.android.com/guide/topics/resources/providing-resources.html#Alternative%20Resources

В частности, попробуйте:

font-zh-rCN

Как @SeanBarbeau указал, правильный шаблон должен быть {language}-r{country}.

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

Как изменить язык (и соответствующий шрифт) в приложении

Короткий ответ заключается в обертывании контекста в onAttachBaseContext a BaseActivity.
В частности, я следовал руководству здесь.

Но для того, чтобы все работало, вам нужно убедиться в двух вещах:

(1) Ваши шрифтовые ресурсы находятся в правильно определенной папке;

На который уже дан ответ в этом потоке, и;

(2) вы завернули контекст в правильный локаль

Я думаю, что это было то, что я пропустил 4 месяца назад. В то время я мало что знал о формате локали.
Я думаю Я продолжал использовать что-то вроде new Locale("zh-CN") или new Locale("zh_CN") или new Locale("zh-rCN"). Все это неправильно!

Лучший способ указать локаль-это использовать встроенные константы, например Locale.SIMPLIFIED_CHINESE.

Если вы посмотрите на эту константу, она вызывает метод createConstant("zh", "CN").
Хотя createConstant() является частным методом, я думаю, что он должен быть таким же, как new Locale("zh", "CN"); но я все же предлагаю использовать константы.

Итак, в конце Ваш ContextWrapper должен выглядеть так:

public static Context wrap(Context context, Locale locale) {
    Configuration config = context.getResources().getConfiguration();
    if (locale == null) locale = Locale.ENGLISH; //Your default locale
    Locale.setDefault(locale);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        config.setLocale(locale);
    } else {
        config.locale = locale;
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        return context.createConfigurationContext(config);
    } else {
        context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
        return context;
    }
}

Здесь речь идет о том, чтобы непосредственно передать a Locale объект для обертки, что отличается от большинства примеров, в которых используется a String.
В то время как преобразование предпочтения (возможно, просто строки) в объект Locale зависит от вашей реализации.