¿Cómo configurar una fuente personalizada para toda una aplicación en Android?

82

¿Es posible configurar una fuente personalizada en una aplicación de Android?

Probé lo que se publica aquí , pero no sé dónde está mi extends Applicationclase ...

¿Alguna ayuda?

EDITAR:

Intenté lo siguiente:

  • Agregue una carpeta de activos e inserte la fuente dentro como se ve aquí:

ingrese la descripción de la imagen aquí

  • Agregue una nueva clase que se extienda desde Application

  • Llame a esta nueva clase de mi AndroidManifest.xml.

  • Fui a mi estilo y lo agregué.

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>

Pero mi fuente todavía no cambia ... ¿alguna idea?

Entonces MyAppse llama a la clase. Pero ningún efecto en mis fuentes ...

EDIT2: Me di cuenta de que mis botones aplican la fuente personalizada después de establecer un estilo personalizado para mis botones. Aquí está mi estilo de botón personalizado:

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

Y así es como se ve ahora:

ingrese la descripción de la imagen aquí

Entonces: mi botón está aplicando el estilo, pero no el TextView. ¿Alguna idea de por qué mi fuente personalizada no se aplica a todos los elementos de la aplicación?

Sonhja
fuente
El enlace que proporcionó en cuestión es realmente útil para su problema.
Androider
Lo sé, creo que mi solución está ahí ... Pero cuando creo una clase que se extiende desde la Aplicación, no puedo hacer que funcione ya que dice que mi clase nunca se usa ...
Sonhja
revise algunos enlaces más en mi respuesta, parece ser útil, una cosa más, mi primer enlace es realmente mejor, Gracias
Androider

Respuestas:

49

Escribe una clase

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

ahora lo siguiente es en AndroidManifest.xml para que la etiqueta de la aplicación dé nombre a su clase de aplicación. En este caso es MyApp

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

Entonces, cada vez que se abre la aplicación, se invoca el método onCreate de la clase MyApp y se establece la fuente.

Actualizar Coloque el archivo de fuente en assets / fonts / your_font_file.ttf

Ponga esta línea debajo del método onCreate de su clase de aplicación (MyApp)

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

Archivo fuente para 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);
            }
        }
    }
}

Ahora actualice su archivo style.xml

ponga la línea de abajo su estilo que se incluye para su actividad en el archivo de manifiesto

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

Espero que esto ayude

Nitin Mesta
fuente
Por favor, avíseme la versión de su sistema operativo Android que está probando. He observado en Lollipop que necesitamos hacer más ajustes
Nitin Mesta
Consulte el siguiente enlace para ver la solución para Lollipop y versiones anteriores de Android: ( stackoverflow.com/a/36206275/2268466 )
blueware
cambia toda la fuente de la aplicación en el mensaje brindis, diálogo de alerta, no quiero usar una fuente personalizada en esto
Adil
1
Tengo una duda, muchos fabricantes permiten al usuario cambiar las fuentes en todo el sistema desde la configuración. ¿Ese cambio también anula el tipo de fuente que configuramos mediante programación?
Bhuro
82

EDITAR

uk.co.chrisjenx:calligraphyLib no se mantiene más para la última versión de Android alternativa ahora es https://github.com/InflationX/Calligraphy

dependencies {
    implementation 'io.github.inflationx:calligraphy3:3.1.1'
    implementation 'io.github.inflationx:viewpump:2.0.3'
}

Agregue sus fuentes personalizadas a los activos /

Uso

Para fuente predeterminada

Defina su fuente predeterminada usando CalligraphyConfig, en su clase Application en el método #onCreate () y páselo al CalligraphyInterceptor que agrega a su constructor ViewPump.

@Override
public void onCreate() {
    super.onCreate();
    ViewPump.init(ViewPump.builder()
        .addInterceptor(new CalligraphyInterceptor(
                new CalligraphyConfig.Builder()
                    .setDefaultFontPath("fonts/Roboto-RobotoRegular.ttf")
                    .setFontAttrId(R.attr.fontPath)
                    .build()))
        .build());
    //....
}

Inyectar en el contexto: envolver el contexto de la actividad:

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

Estilo personalizado

<style name="TextViewCustomFont">
    <item name="fontPath">fonts/RobotoCondensed-Regular.ttf</item>
</style>

Por tema

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/AppTheme.Widget.TextView</item>
</style>

<style name="AppTheme.Widget"/>

<style name="AppTheme.Widget.TextView" parent="android:Widget.Holo.Light.TextView">
    <item name="fontPath">fonts/Roboto-ThinItalic.ttf</item>
</style>

No más mantenido por desarrolladores debajo de la solución


Hay una gran biblioteca para fuentes personalizadas en Android: Caligrafía
Aquí hay una muestra de cómo usarlo.

En Gradle, debe poner esta línea en el archivo build.gradle de su aplicación:

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

Y luego crea una clase que amplíe Application y escribe este código:

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

Debería haber hecho en assets / un "Nuevo directorio" "fuentes" (ver más abajo), por lo que en ese código "su ruta de fuente" debe ser "fuentes / SourceSansPro-Regular.ttf". (Son solo "fuentes ..." no "/ fuentes ..." o "recursos ...")

Y en la clase de actividad ponga este método antes de onCreate:

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

Y la última cosa que su archivo de manifiesto debería verse así:

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

¡Y cambiará toda la actividad a tu fuente! ¡es simple y limpio!

En Activos, debe hacer clic con el botón derecho en Nuevo directorio, llamarlo "fuentes". En el buscador, coloque los .ttfarchivos de fuentes allí.

ingrese la descripción de la imagen aquí

Además, no olvide agregar debajo de dos líneas en attrs.xml, si no tiene el archivo attrs.xml, cree un nuevo archivo en values.xml

 <attr format="string" name="fontPath"/> 
    <item name="calligraphy_tag_id" type="id"/>
Rajesh Nasit
fuente
Estoy usando ttf pero estoy bastante seguro de que .otf también funcionará y la mejor ubicación para ponerlo en la carpeta de activos.
Rajesh Nasit
Ponga esto en la clase de aplicación extendida CalligraphyConfig.initDefault (new CalligraphyConfig.Builder () .setDefaultFontPath ("fonts / GOTHAM-MEDIUM.ttf") .setFontAttrId (R.attr.fontPath) .build ()); Tampoco olvide agregar debajo de dos líneas en values.xml <attr format = "string" name = "fontPath" /> <item name = "calligraphy_tag_id" type = "id" />
Rajesh Nasit
hola @rajesh! debe hacer clic en "Editar" y agregar eso a su gran respuesta. tienes razón, deberían ser archivos .ttf , lo siento.
Fattie
1
Puede utilizar el fragmento lo máximo posible. Entonces ese número de actividad se reducirá.
Rajesh Nasit
1
@Pawan para hacerlo en un paso: defino una clase base simple donde attachBaseContext(..)se implementa, y luego todas las clases de actividad de mi proyecto (donde quiero esa fuente personalizada) extienden esa clase base
Gene Bo
63

Todo lo que hice fue:

1: Se agregó "nuevo directorio de recursos" a la carpeta RES, se seleccionó el TIPO DE RECURSO como "fuente" en el menú desplegable, se denominó "fuente" al nuevo directorio y se guardó. DIRECTORIO DE NUEVOS RECURSOS

2: Agregué mi "custom_font.ttf" a la carpeta FONT recién creada.

3: Agregué mi fuente personalizada en el tema base de la aplicación en STYLES.XML

ESTILOS.XML

HECHO.

Numanqmr
fuente
4
También tienes que crear una familia de fuentes. Después de eso funcionó para mí. Detalles aquí: developer.android.com/guide/topics/ui/look-and-feel/…
keybee
funcionó para mí sin tener que crear una familia de fuentes. Sin embargo, tuve que usar Gradle versión> 3 y construir herramientas y soportar bibliotecas configuradas en 27> @keybee
Numanqmr
Funcionó muy bien para mí, incluso sin familia tipográfica
Julian Alberto
¿Sabes cómo cambiarlo programáticamente?
majov
@majov revisa la respuesta anterior por #Rajeesh. eso debería ayudarte!
Numanqmr
12

Puede hacerlo con el SDK de Android ahora, ya que el canal oficial de YouTube para desarrolladores de Android publicado en set / 2017 aquí .

Requiere API nivel 26 (Android 8 Oreo) y superior.

Solo necesita poner su archivo de fuente en la res/fontcarpeta y hacer referencia a ellos en su TextViewcaso que necesite uno específico con el android:fontFamilyatributo.

Si desea una fuente base en toda su aplicación, simplemente coloque

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

en tus styles.xml

Puede descargar una fuente personalizada desde Android Studio y sobre la marcha si lo desea también. Todo esto lo puedes encontrar con detalles en el video de arriba.

Francisco Nin
fuente
Esta opción es para API 26 y superior. No 16+
Perfect Square
¿Qué tal arreglar API 23 +?
Raju yourPepe
12

Android ofrece las mejores y más sencillas soluciones que son compatibles con el nivel de API 14 por Support Library 26+. Fuentes en XML También admite la opción de familia de fuentes . Importación requerida: implementation "com.android.support:support-compat:<26+ version>"

Siga estos sencillos pasos y la familia de fuentes se aplicará en su aplicación sin ningún obstáculo:

  1. Crea un directorio de fuentes dentro de res
  2. Pegue su archivo de fuentes dentro de la fuente
  3. Haga clic con el botón derecho en la carpeta de fuentes y vaya a Nuevo> Archivo de recursos de fuentes. Aparece la ventana Nuevo archivo de recursos.
  4. Agregar los siguientes atributos
<?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. En el archivo xml anterior. Use la aplicación solo para usar la biblioteca de soporte. De lo contrario, puede usar Android si su aplicación tiene como objetivo el nivel de API 26+.
  2. Ahora vaya a su styles.xml y coloque la línea debajo de su estilo principal.
    <item name="android:fontFamily">@font/opensans</item>
    
  3. Importante: use AppCompatActivity solo si está usando la biblioteca de soporte.
  4. O use a continuación para configurar el tipo de letra mediante programación

    view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
    
Kuldeep Sakhiya
fuente
De esta manera es compatible con la función actual de recursos de fuentes de Android. Gracias.
azwar_akbar
2

Parece que está usando en android:fontFamilylugar de android:typefaceen su styles.xml.

Intenta reemplazar

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

con

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:typeface">default</item>
</style>
Suhas
fuente
1
¿Y cómo lo conecto con mi aplicación? ¿Quién se extiende de ella?
Sonhja
Bueno, al extender Application, simplemente está creando una subclase de la clase de su aplicación Application. Entonces, no es necesario que lo conectes.
Suhas
¿Qué dice que nunca se usa?
Suhas
¿También agregó una <item name="android:typeface">default</item>línea dentro <style name="AppTheme" parent="AppBaseTheme">del res -> values -> styles.xmlarchivo de su aplicación como se sugiere en la misma publicación SO?
Suhas
Sí, y tampoco funciona. Eso es justo lo que puse en mi edición ... :(
Sonhja
2

Si sigue el primer tema, esto debería funcionar: Aquí

Sí, con reflexión. Esto funciona ( basado en esta respuesta ):

(Nota: esta es una solución debido a la falta de soporte para fuentes personalizadas, por lo que si desea cambiar esta situación, marque para votar el problema de Android aquí). Nota: No dejes comentarios de "yo también" sobre ese tema, todos los que lo han mirado recibirán un correo electrónico cuando lo hagas. Así que sólo "destaque" por favor.

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

Luego necesita sobrecargar las pocas fuentes predeterminadas, por ejemplo, en una clase de aplicación:

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");
    }
}

Por supuesto, si está utilizando el mismo archivo de fuente, puede mejorarlo para cargarlo solo una vez.

Sin embargo, tiendo a anular uno, decir "MONOSPACIO", luego configurar un estilo para forzar que la aplicación de tipo de letra sea amplia:

<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

Investigué los informes en los comentarios de que no funciona y parece ser incompatible con el tema Android: Theme.Material.Light.

Si ese tema no es importante para usted, use un tema más antiguo, por ejemplo:

<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:typeface">monospace</item>
</style>
Robin Delaporte
fuente
1

Cree la carpeta de activos en la carpeta principal, agregue la carpeta de fuentes en ella. agregue su archivo .ttf en la carpeta de fuentes.

Agregue lo siguiente en el tema de su aplicación:

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

Crear clase como 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);
        }
    }
}

Llámalo en la clase de aplicación o en la actividad del Lanzador.

        TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
Pratibha Sarode
fuente
1
  1. Al principio, debe hacer clic con el botón derecho en los recursos de su proyecto cuyo nombre y resluego de la newopción elegir Android Resource Directoryy seleccionar fontformulario Resource typey presionar OK, esto creará un directorio de fuentes para colocar sus fuentes en él.

ingrese la descripción de la imagen aquí

  1. Pon tus .ttfarchivos de fuentes ahí.

ingrese la descripción de la imagen aquí

  1. Vaya al archivo de estilo del proyecto que existe en la siguiente ruta res/values/styles.xml y agregue estilos como ese:

    <style name="SansSerifFont">
        <item name="android:fontFamily">sans-serif</item>
    </style>
    
    <style name="OpenSansFont">
        <item name="android:fontFamily">@font/open_sans</item>
    </style>
    
    <style name="IranianSansFont">
        <item name="android:fontFamily">@font/iranian_sans</item>
    </style>
    
    <style name="BYekanFont">
        <item name="android:fontFamily">@font/b_yekan</item>
    </style>
    
    <style name="DroidArabicFont">
        <item name="android:fontFamily">@font/droid_arabic</item>
    </style>
    
  2. Vaya a su código y escriba una clase como esta para cambiar la fuente de toda la aplicación:

    public class AppFontManager {
    
        private AppCompatActivity appCompatActivity;
    
        public static final String SANS_SERIF_APP_FONT = "sans_serif";
        public static final String B_YEKAN_APP_FONT = "b_yekan";
        public static final String DROID_ARABIC_APP_FONT = "droid_arabic";
        public static final String IRANIAN_SANS_APP_FONT = "iranian_sans";
        public static final String OPEN_SANS_APP_FONT = "open_sans";
    
        public AppAppearanceManager(AppCompatActivity appCompatActivity) {
            this.appCompatActivity = appCompatActivity;
        }
    
        public void setFont(String fontName){
    
            switch (fontName){
    
                case SANS_SERIF_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.SansSerifFont, true);
                    break;
                }
    
                case B_YEKAN_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.BYekanFont, true);
                    break;
                }
    
                case DROID_ARABIC_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.DroidArabicFont, true);
                    break;
                }
    
                case IRANIAN_SANS_APP_FONT:{
                appCompatActivity.getTheme().applyStyle(R.style.IranianSansFont, true);
                    break;
                }
    
                case OPEN_SANS_APP_FONT:{
                    appCompatActivity.getTheme().applyStyle(R.style.OpenSansFont, true);
                    break;
                }
            }
        }
    }
    

    Debido a que las fuentes deben establecerse por separado para cada actividad, prefiero escribir una clase para un código más limpio.

  3. Luego llame al método de clase antes de la actividad onCreate super.onCreate(savedInstanceState):

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        new AppAppearanceManager(this).setFont(APP_DEFAULT_FONT);
        super.onCreate(savedInstanceState);
    // Do you stuff there...
    }
    

    Recuerde que si desea cambiar la fuente durante el tiempo de ejecución , escriba una fuente elegida en SharedPreferenceso etc, luego pase la fuente elegida a todas las actividades setFontcomo arriba.

Mohsen Pakzad
fuente
0

Primero, cree una nueva clase que anule cualquier Vista que desee personalizar. (por ejemplo, ¿quieres un botón con un tipo de letra personalizado? Ampliar Button). Por ejemplo:

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

Ahora, si no tiene uno, agregue un documento XML debajo res/values/attrs.xmly agregue:

<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>

Bien, con eso fuera del camino, volvamos al parseAttributes()método de antes:

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

Ahora estás listo. Puede agregar más atributos para casi cualquier cosa (podría agregar otro para typefaceStyle: negrita, cursiva, etc.) pero ahora veamos cómo usarlo:

<?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>

La xmlns:customlínea realmente puede ser cualquier cosa, pero la convención es lo que se muestra arriba. Lo que importa es que es único y por eso se usa el nombre del paquete. Ahora solo usa el custom:prefijo para tus atributos y el android:prefijo para los atributos de Android.

Una última cosa: si quiere utilizar esto en un estilo ( res/values/styles.xml), debe no agregar la xmlns:customlínea. Simplemente haga referencia al nombre del atributo sin prefijo:

<style name="MyStyle>
    <item name="typeface">roboto</item>
</style>
Archit Goel
fuente
0

También probé la anulación de fuentes, pero al final no es una solución confiable, lamentablemente las fuentes anuladas requieren más que eso. Puede esperar a que aparezca Android O con fuente personalizada o usar una biblioteca de terceros.

La última solución que encontré fue esta biblioteca de Caligrafía , que fue fácil de iniciar y te permitió usar tantas fuentes como quieras. Mientras revisaba su código fuente, entendí por qué simplemente anular las fuentes no funcionaría, así que incluso si no planea usarlo, le recomiendo leerlo una vez.

Buena suerte

Keivan Esbati
fuente
Sí ... quizás. De todos modos, háganos saber si encontró una razón detrás de este problema, se lo agradecería mucho. No pude encontrar una solución ni siquiera leyendo los códigos subyacentes.
Keivan Esbati
0

Pruebe el siguiente código, funciona para mí, espero que también lo ayude.

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) {
 }
 }
}

Ahora extienda esta BaseActivity a cualquiera de sus actividades o puede crear la misma clase para el fragmento si está usando.

Nota: - Si desea configurar algunos de los tipos de letra de vista diferentes, debe configurarlos mediante programación como se muestra a continuación

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

Así que pruébalo y avísame, si puedo ayudarte más

Bhavnik
fuente
0

Un trabajo alternativo para Kotlin será este

Resumen de la solución https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7

Paso uno

Coloque el archivo de fuente en assets / fonts / your_font_file.ttf y cree una clase kotlin llamada 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")
        }
    }
}

Paso dos Luego en tuonCreate

val typefaceUtil = TypefaceUtil()

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

Paso tres

agrega esto a tu estilo

<item name="android:typeface">serif</item>
Johnyoat
fuente
0

Los nombres de las fuentes deben estar en minúsculas para que se muestren en la aplicación y el trabajo.

Mazhar Ali
fuente