Вопрос:

Как установить собственный шрифт для всего приложения в Android?

android

51510 просмотра

12 ответа

4513 Репутация автора

Можно ли установить собственный шрифт в приложении для Android?

Я попробовал то, что опубликовано здесь , но я не знаю, где мой extends Applicationкласс ...

Любая помощь?

РЕДАКТИРОВАТЬ:

Я попробовал следующее:

  • Добавьте папку ресурсов и вставьте шрифт внутрь, как показано здесь:

введите описание изображения здесь

  • Добавьте новый класс, который расширяется от Application

  • Назовите этот новый класс от моего AndroidManifest.xml.

  • Я пошел в свой стиль и добавил его.

MyApp.java:

public class MyApp extends Application {
  @Override
  public void onCreate() {
     super.onCreate();
    FontsOverride.setDefaultFont(this, "DEFAULT", "raleway_regular.ttf");
    //  This FontsOverride comes from the example I posted above
  }
  }

AndroidManifest.xml:

<application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true"
      android:name=".MyApp"
      android:theme="@style/AppTheme">
     ....

styles.xml:

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:fontFamily">default</item>
 </style>

Но мой шрифт все еще не меняется ... есть идеи?

Тогда MyAppкласс называется. Но не влияет на мои шрифты ...

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

<style name="MyButtonStyle" parent="Widget.AppCompat.Button">
    <item name="textAllCaps">false</item>
    <item name="android:textAllCaps">false</item>
</style>

А вот как это выглядит сейчас:

введите описание изображения здесь

Итак: моя кнопка применяет стиль, но не TextView. Любая идея о том, почему мой пользовательский шрифт не применяется для всех элементов в приложении?

Автор: Sonhja Источник Размещён: 25.11.2015 06:21

Ответы (12)


2 плюса

1148 Репутация автора

Похоже, что вы используете, android:fontFamilyа не android:typefaceв вашем styles.xml.

Попробуйте заменить

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:fontFamily">default</item>
</style>

с

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:typeface">default</item>
</style>
Автор: Suhas Размещён: 25.11.2015 06:23

43 плюса

1106 Репутация автора

Решение

Написать класс

public class MyApp extends Application{
// Put the onCreate code as you obtained from the post link you reffered
}

теперь следующая вещь находится в AndroidManifest.xml для тега приложения, дайте имя вашему классу приложения. В данном случае это MyApp

<application
android:name=".MyApp"
...
>
...
</application>

Таким образом, всякий раз, когда приложение открывается, вызывается метод onCreate класса MyApp и устанавливается шрифт.

Обновление Поместите файл шрифта в assets / fonts / your_font_file.ttf

Поместите эту строку в метод onCreate вашего класса приложения (MyApp)

TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/your_font_file.ttf");

Исходный файл для TypefaceUtil

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     *
     * @param context                    to work with assets
     * @param defaultFontNameToOverride  for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {

        final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Map<String, Typeface> newMap = new HashMap<String, Typeface>();
            newMap.put("serif", customFontTypeface);
            try {
                final Field staticField = Typeface.class
                        .getDeclaredField("sSystemFontMap");
                staticField.setAccessible(true);
                staticField.set(null, newMap);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            try {
                final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
                defaultFontTypefaceField.setAccessible(true);
                defaultFontTypefaceField.set(null, customFontTypeface);
            } catch (Exception e) {
                Log.e(TypefaceUtil.class.getSimpleName(), "Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
            }
        }
    }
}

Теперь обновите ваш файл style.xml

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

  <item name="android:typeface">serif</item>

Надеюсь это поможет

Автор: Nitin Mesta Размещён: 25.11.2015 06:29

0 плюса

648 Репутация автора

Сначала создайте новый класс, который переопределяет любой вид, который вы хотите настроить. (например, хотите кнопку с пользовательским шрифтом? Расширить Button). Например:

public class CustomButton extends Button {
    private final static int ROBOTO = 0;
    private final static int ROBOTO_CONDENSED = 1;

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

    public CustomButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        parseAttributes(context, attrs); //I'll explain this method later
    }

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

Теперь, если у вас его нет, добавьте XML-документ res/values/attrs.xmlи добавьте:

<resources>
    <!-- Define the values for the attribute -->
    <attr name="typeface" format="enum">
        <enum name="roboto" value="0"/>
        <enum name="robotoCondensed" value="1"/>
    </attr>

    <!-- Tell Android that the class "CustomButton" can be styled, 
         and which attributes it supports -->
    <declare-styleable name="CustomButton">
        <attr name="typeface"/>
    </declare-styleable>
</resources>

Хорошо, так с этим из пути, давайте вернемся к parseAttributes()методу из ранее:

private void parseAttributes(Context context, AttributeSet attrs) {
    TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);

    //The value 0 is a default, but shouldn't ever be used since the attr is an enum
    int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);

    switch(typeface) {
        case ROBOTO: default:
            //You can instantiate your typeface anywhere, I would suggest as a 
            //singleton somewhere to avoid unnecessary copies
            setTypeface(roboto); 
            break;
        case ROBOTO_CONDENSED:
            setTypeface(robotoCondensed);
            break;
    }

    values.recycle();
}

Теперь все готово. Вы можете добавить больше атрибутов для чего угодно (вы можете добавить еще один для typefaceStyle - жирный, курсив и т. Д.), Но теперь давайте посмотрим, как его использовать:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.yourpackage.name.CustomButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me!"
        custom:typeface="roboto" />

</LinearLayout>

xmlns:customЛиния действительно может быть что угодно, но соглашение является то , что показано выше. Важно то, что он уникален, и поэтому используется имя пакета. Теперь вы просто используете custom:префикс для своих атрибутов и android:префикс для атрибутов Android.

One last thing: if you want to use this in a style (res/values/styles.xml), you should not add the xmlns:custom line. Just reference the name of the attribute with no prefix:

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>
Автор: Archit Goel Размещён: 25.11.2015 06:30

2 плюса

529 Репутация автора

Если вы следуете первой теме, это должно работать: здесь

Да с отражением. Это работает ( основываясь на этом ответе ):

(Примечание: это обходной путь из-за отсутствия поддержки пользовательских шрифтов, поэтому, если вы хотите изменить эту ситуацию, пожалуйста, отметьте звездочку, чтобы проголосовать за проблему Android). Примечание: не оставляйте комментарии "Я тоже" по этому вопросу, все, кто смотрел его, получают по электронной почте, когда вы делаете это. Так что просто "звезда", пожалуйста.

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride {

public static void setDefaultFont(Context context,
        String staticTypefaceFieldName, String fontAssetName) {
    final Typeface regular = Typeface.createFromAsset(context.getAssets(),
            fontAssetName);
    replaceFont(staticTypefaceFieldName, regular);
}

protected 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();
    }
}
}

Затем вам нужно перегрузить несколько шрифтов по умолчанию, например, в классе приложения:

public final class Application extends android.app.Application {
    @Override
    public void onCreate() {
        super.onCreate();
        FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
        FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
    }
}

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

Однако я склонен просто переопределить один, скажем, «MONOSPACE», а затем установить стиль, чтобы расширить шрифт приложения:

<resources>
    <style name="AppBaseTheme" parent="android:Theme.Light">
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <item name="android:typeface">monospace</item>
    </style>
</resources>

API 21 Android 5.0

Я исследовал сообщения в комментариях, что он не работает, и кажется, что он несовместим с темой Android: Theme.Material.Light.

Если эта тема не важна для вас, используйте старую тему, например:

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>
Автор: Robin Delaporte Размещён: 22.01.2017 12:07

67 плюса

2270 Репутация автора

В Android есть отличная библиотека для пользовательских шрифтов: Каллиграфия
Вот пример того, как ее использовать.

В Gradle вам нужно поместить эту строку в файл build.gradle вашего приложения:

        dependencies {
            compile 'uk.co.chrisjenx:calligraphy:2.2.0'
        }

А затем создайте класс, расширяющий Application, и напишите этот код:

        public class App extends Application {
            @Override
            public void onCreate() {
                super.onCreate();

                CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
                                .setDefaultFontPath("your font path")
                                .setFontAttrId(R.attr.fontPath)
                                .build()
                );
            }
        } 

Вы должны были сделать для assets / a "New Directory" "шрифты" (см. Ниже), поэтому в этом коде "ваш путь шрифта" должен быть "fonts / SourceSansPro-Regular.ttf". (Это просто "шрифты ...", а не "/ шрифты .." или "активы ..")

И в классе активности поместите этот метод перед onCreate:

        @Override
        protected void attachBaseContext(Context newBase) {
            super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
        }

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

        <application
           .
           .
           .
           android:name=".App">

И это изменит всю активность на ваш шрифт! это просто и чисто!

На Активах вы должны щелкнуть правой кнопкой мыши Новый каталог, назовите его «шрифты». В поисковике поместите .ttfтуда файлы шрифтов.

введите описание изображения здесь

Также не забудьте добавить ниже две строки в attrs.xml, если у вас нет файла attrs.xml, создайте новый файл в values.xml

 <attr format="string" name="fontPath"/> 
    <item name="calligraphy_tag_id" type="id"/>
Автор: Rajesh Nasit Размещён: 14.02.2017 05:54

0 плюса

1866 Репутация автора

I have tried font override too but at the end it's not a reliable solution, sadly overriding fonts take more than that. You can either wait for Android O with custom font to comes out or use a third party library.

The last solution that I came across was this library Caligraphy , which was easy to initiate and let you use as many font as you want. While checking its source code I understood why just overriding fonts won't work so even if you don't plan to use it I recommend reading through it once..

Good luck

Автор: Keivan Esbati Размещён: 16.04.2017 05:58

0 плюса

1299 Репутация автора

Try below code, it works for me, Hope it'll help you too.

public class BaseActivity extends AppCompatActivity {

private Typeface typeace;
@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    typeace = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name));
}

@Override
protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();
    overrideFonts(this,getWindow().getDecorView());
}

private 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(typeace);
        } else if (v instanceof EditText ) {
            ((EditText) v).setTypeface(typeace);
        } else if (v instanceof Button) {
            ((Button) v).setTypeface(typeace);
        }
    } catch (Exception e) {
 }
 }
}

Теперь расширьте эту BaseActivity на любую из ваших Activity, или вы можете создать тот же класс для фрагмента, если вы используете.

Примечание: - Если вы хотите установить другой вид шрифта, вы должны установить это программно, как показано ниже

private Typeface typeface;
typeface = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name_bold));
tvUserName.setTypeface(typeface);

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

Автор: Bhavnik Размещён: 18.04.2017 12:22

27 плюса

418 Репутация автора

Все, что я сделал, было:

1: Добавлен «новый каталог ресурсов» в папку RES, выбранный ТИП РЕСУРСА как «шрифт» из выпадающего списка, назван новый каталог «шрифт» и сохранен. НОВЫЙ РЕСУРСНЫЙ КАТАЛОГ

2: Добавлен мой "custom_font.ttf" в только что созданную папку FONT.

3: Добавлен мой собственный шрифт в базовую тему приложения в STYLES.XML

styles.xml

СДЕЛАННЫЙ.

Автор: Numanqmr Размещён: 07.02.2018 07:48

9 плюса

119 Репутация автора

Вы можете сделать это с помощью Android SDK прямо сейчас, так как официальный канал Android Developer на YouTube опубликован здесь / 2017 здесь .

Требуется API уровня 26 (Android 8 Oreo) и выше.

Вам просто нужно поместить файл шрифта в res/fontпапку и ссылаться на него в вашем TextViewслучае, если вам нужен конкретный файл с android:fontFamilyатрибутом.

Если вы хотите использовать базовый шрифт для всего приложения, просто

<item name="android:fontFamily">@font/yourfontname</item> 

в вашем styles.xml

Вы можете скачать собственный шрифт из Android Studio и на ходу, если хотите. Все это вы можете найти с деталями на видео выше.

Автор: Francisco Nin Размещён: 04.07.2018 06:24

1 плюс

984 Репутация автора

Создайте папку активов в главной папке шрифтов folder.add в ней. добавьте ваш файл .ttf в папку шрифтов.

Добавьте следующее в ваше приложение Тема:

 <item name="android:fontFamily">@font/roboto_regular</item>
    <item name="fontFamily">@font/roboto_regular</item>

Создать класс как TypefaceUtil

 import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;

import java.lang.reflect.Field;

public class TypefaceUtil {

    /**
     * Using reflection to override default typeface
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
     * @param context to work with assets
     * @param defaultFontNameToOverride for example "monospace"
     * @param customFontFileNameInAssets file name of the font from assets
     */
    public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
        try {
            final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);

            final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
            defaultFontTypefaceField.setAccessible(true);
            defaultFontTypefaceField.set(null, customFontTypeface);
        } catch (Exception e) {
            Log.e("Can not set","Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
        }
    }
}

Назовите это в классе приложения или в действии Launcher

        TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
Автор: Pratibha Sarode Размещён: 27.10.2018 05:19

0 плюса

2451 Репутация автора

Android предоставляет более простые и лучшие решения, которые поддерживаются на уровне API 14 библиотекой поддержки 26+. Шрифты в XML Также поддерживается опция семейства шрифтов .

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

  1. Создайте каталог шрифтов внутри res
  2. Вставьте файл шрифтов внутри шрифта
  3. Щелкните правой кнопкой мыши папку шрифтов и выберите «Создать»> «Файл ресурсов шрифта». Откроется окно «Новый файл ресурсов».
  4. Добавить следующие атрибуты
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>
  1. В приведенном выше XML-файле. Используйте приложение только для использования библиотеки поддержки. В противном случае вы можете использовать Android, если ваше приложение нацелено на уровень API 26+.
  2. Теперь перейдите в ваш файл styles.xml и поместите нижнюю строку в свой основной стиль.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. Важное замечание : Используйте AppCompatActivity только в том случае, если вы используете библиотеку поддержки.
  4. Или используйте ниже, чтобы установить гарнитуру программно

    view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
    
Автор: Kuldeep Sakhiya Размещён: 03.06.2019 09:14

0 плюса

116 Репутация автора

Работа вокруг для kotlin будет этим

Суть решения https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

Первый шаг

Поместите файл шрифта в assets / fonts / your_font_file.ttf и создайте класс kotlin с именем TypeFaceUtil

   class TypefaceUtil{

    fun overridefonts(context: Context, defaultFontToOverride:String, customFontFileNameInAssets:String){
        try {
            val customTypeface = Typeface.createFromAsset(context.assets,customFontFileNameInAssets)
            val defaultTypefaceField = Typeface::class.java.getDeclaredField(defaultFontToOverride)
            defaultTypefaceField.isAccessible = true
            defaultTypefaceField.set(null,customTypeface)
        }catch (e:Exception){
            Timber.e("Cannot set font $customFontFileNameInAssets instead of $defaultFontToOverride")
        }
    }
}

Шаг второй Затем в вашем наonCreate

val typefaceUtil = TypefaceUtil()

typefaceUtil.overridefonts(this,"SERIF","fonts/font_file.ttf")

Шаг третий

добавь это в свой стиль

<item name="android:typeface">serif</item>
Автор: Jay Размещён: 13.06.2019 03:54
Вопросы из категории :
32x32