Cómo configurar la familia de fuentes predeterminada para toda la aplicación Android


Estoy usando la fuente Roboto light en mi aplicación. Para establecer la fuente tengo que añadir el android:fontFamily="sans-serif-light" a cada vista. ¿Hay alguna manera de declarar la fuente Roboto como familia de fuentes predeterminada para toda la aplicación? Lo he intentado así, pero no ha funcionado.

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

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:fontFamily">sans-serif-light</item>
</style>
Author: tomrozb, 2013-05-06

12 answers

La respuesta es sí.

Luz Roboto global para las clases TextView y Button:

<style name="AppTheme" parent="AppBaseTheme">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="android:buttonStyle">@style/RobotoButtonStyle</item>
</style>

<style name="RobotoTextViewStyle" parent="android:Widget.TextView">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="RobotoButtonStyle" parent="android:Widget.Holo.Button">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

Simplemente seleccione el estilo que desee de los temas list .xml , luego cree su estilo personalizado basado en el original. Al final, aplique el estilo como el tema de la aplicación.

<application
    android:theme="@style/AppTheme" >
</application>

Solo funcionará con fuentes integradas como Roboto, pero esa era la pregunta. Para fuentes personalizadas (cargadas desde activos, por ejemplo) este método no funcionará.

EDITAR 08/13/15

Si estás usando temas AppCompat, recuerda eliminar el prefijo android:. Por ejemplo:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textViewStyle">@style/RobotoTextViewStyle</item>
    <item name="buttonStyle">@style/RobotoButtonStyle</item>
</style>

Tenga en cuenta que el buttonStyle no contiene el prefijo android:, pero textViewStyle debe contenerlo.

 228
Author: tomrozb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-07 20:10:56

Con el lanzamiento de Android Oreo puede utilizar la biblioteca de soporte para alcanzar este objetivo.

  1. Comprueba la compilación de tu app .gradle si tienes la biblioteca de soporte >= 26.0.0
  2. Agregue la carpeta "font " a su carpeta de recursos y agregue sus fuentes allí
  3. Haga referencia a su familia de fuentes predeterminada en el estilo principal de su aplicación:

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
       <item name="android:fontFamily">@font/your_font</item>
       <item name="fontFamily">@font/your_font</item> <!-- target android sdk versions < 26 and > 14 if theme other than AppCompat -->
    </style>
    

Compruebe https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html para información más detallada.

 69
Author: João Magalhães,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-06 15:40:16

Puedes usar la caligrafía para administrar fuentes con Android

Https://github.com/chrisjenx/Calligraphy

 42
Author: AndroidGecko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-27 11:01:02

LEA LAS ACTUALIZACIONES A CONTINUACIÓN

Tuve el mismo problema con la incrustación de una nueva fuente y finalmente lo conseguí para trabajar con la extensión de TextView y establecer el tipo de letra dentro.

public class YourTextView extends TextView {

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

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

    public YourTextView(Context context) {
        super(context);
        init();
    }

    private void init() {
        Typeface tf = Typeface.createFromAsset(context.getAssets(),
            "fonts/helveticaneue.ttf");
        setTypeface(tf);
    }
}

Tiene que cambiar los elementos TextView más tarde a from a en cada elemento. Y si usas el UI-Creator en Eclipse, a veces no muestra las vistas de texto correctamente. Era lo único que funcionaba para mí...

UPDATE

Hoy en día estoy usando la reflexión para cambiar los tipos de letra en toda la aplicación sin extender TextViews. Echa un vistazo a esto para publicar

ACTUALIZACIÓN 2

A partir del nivel de API 26 y disponible en 'biblioteca de soporte', puede usar

android:fontFamily="@font/embeddedfont"

Más información: Fuentes en XML

 28
Author: longilong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-08 10:10:46

No hablar de rendimiento, para la fuente personalizada puede tener un bucle de método recursivo a través de todas las vistas y establecer el tipo de letra si se trata de una vista de texto:

public class Font {
    public static void setAllTextView(ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setAllTextView((ViewGroup) child);
            } else if (child instanceof TextView) {
                ((TextView) child).setTypeface(getFont());
            }
        }
    }

    public static Typeface getFont() {
        return Typeface.createFromAsset(YourApplicationContext.getInstance().getAssets(), "fonts/whateverfont.ttf");
    }
}

En toda tu actividad, pásale current ViewGroup después de setContentView y listo:

ViewGroup group = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
Font.setAllTextView(group);

Para fragment puedes hacer algo similar.

 6
Author: Allen Chan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-25 10:19:07

Otra forma de hacer esto para toda la aplicación es usar reflexión basada en esta respuesta

public class TypefaceUtil {
    /**
     * Using reflection to override default typefaces
     * NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE
     * OVERRIDDEN
     *
     * @param typefaces map of fonts to replace
     */
    public static void overrideFonts(Map<String, Typeface> typefaces) {
        try {
            final Field field = Typeface.class.getDeclaredField("sSystemFontMap");
            field.setAccessible(true);
            Map<String, Typeface> oldFonts = (Map<String, Typeface>) field.get(null);
            if (oldFonts != null) {
                oldFonts.putAll(typefaces);
            } else {
                oldFonts = typefaces;
            }
            field.set(null, oldFonts);
            field.setAccessible(false);
        } catch (Exception e) {
            Log.e("TypefaceUtil", "Can not set custom fonts");
        }
    }

    public static Typeface getTypeface(int fontType, Context context) {
        // here you can load the Typeface from asset or use default ones
        switch (fontType) {
            case BOLD:
                return Typeface.create(SANS_SERIF, Typeface.BOLD);
            case ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.ITALIC);
            case BOLD_ITALIC:
                return Typeface.create(SANS_SERIF, Typeface.BOLD_ITALIC);
            case LIGHT:
                return Typeface.create(SANS_SERIF_LIGHT, Typeface.NORMAL);
            case CONDENSED:
                return Typeface.create(SANS_SERIF_CONDENSED, Typeface.NORMAL);
            case THIN:
                return Typeface.create(SANS_SERIF_MEDIUM, Typeface.NORMAL);
            case MEDIUM:
                return Typeface.create(SANS_SERIF_THIN, Typeface.NORMAL);
            case REGULAR:
            default:
                return Typeface.create(SANS_SERIF, Typeface.NORMAL);
        }
    }
}

Luego, cada vez que desee anular las fuentes, puede llamar al método y darle un mapa de tipos de letra de la siguiente manera:

Typeface regular = TypefaceUtil.getTypeface(REGULAR, context);
Typeface light = TypefaceUtil.getTypeface(REGULAR, context);
Typeface condensed = TypefaceUtil.getTypeface(CONDENSED, context);
Typeface thin = TypefaceUtil.getTypeface(THIN, context);
Typeface medium = TypefaceUtil.getTypeface(MEDIUM, context);
Map<String, Typeface> fonts = new HashMap<>();
fonts.put("sans-serif", regular);
fonts.put("sans-serif-light", light);
fonts.put("sans-serif-condensed", condensed);
fonts.put("sans-serif-thin", thin);
fonts.put("sans-serif-medium", medium);
TypefaceUtil.overrideFonts(fonts);

Para el ejemplo completo marque

Esto solo funciona para Android SDK 21 y superior para versiones anteriores consulte el ejemplo completo

 3
Author: Ismail Almetwally,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:29

Simplemente use esta lib compílela en su archivo de calificación

complie'me.anwarshahriar:calligrapher:1.0'

Y utilizarlo en el método onCreate en la actividad principal

Calligrapher calligrapher = new Calligrapher(this);
calligrapher.setFont(this, "yourCustomFontHere.ttf", true);

Esta es la forma más elegante y súper rápida de hacerlo.

 2
Author: Mohamed Ayed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-24 03:36:13

Android no proporciona mucho soporte para la aplicación de fuentes en toda la aplicación (consulte este problema ). Tienes 4 opciones para establecer la fuente para toda la aplicación:

  • Opción1: Aplicar reflexión para cambiar la fuente del sistema
  • Option2: Crear y subclase clases de vista personalizada para cada vista que necesita una fuente personalizada
  • Option3: Implementar un rastreador de vistas que atraviese la vista jerarquía para la pantalla actual
  • Opción4: Usar una tercera parte biblioteca.

Los detalles de estas opciones se pueden encontrar aquí.

 0
Author: Phileo99,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:27

Sé que esta pregunta es bastante antigua, pero he encontrado una buena solución. Básicamente, pasa un diseño de contenedor a esta función, y aplicará la fuente a todas las vistas compatibles, y cíclicamente en diseños secundarios:

public static void setFont(ViewGroup layout)
{
    final int childcount = layout.getChildCount();
    for (int i = 0; i < childcount; i++)
    {
        // Get the view
        View v = layout.getChildAt(i);

        // Apply the font to a possible TextView
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Apply the font to a possible EditText
        try {
            ((TextView) v).setTypeface(MY_CUSTOM_FONT);
            continue;
        }
        catch (Exception e) { }

        // Recursively cicle into a possible child layout
        try {
            ViewGroup vg = (ViewGroup) v;
            Utility.setFont(vg);
            continue;
        }
        catch (Exception e) { }
    }
}
 0
Author: FonzTech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-08 13:15:38

Para establecer simplemente el tipo de letra de la aplicación a normal, sans, serif o monospace (¡no a una fuente personalizada!), usted puede hacer esto.

Define un tema y establece el atributo android:typeface al tipo de letra que deseas usar en styles.xml:

<resources>

    <!-- custom normal activity theme -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- other elements -->
        <item name="android:typeface">monospace</item>
    </style>

</resources>

Aplica el tema a toda la aplicación en el archivo AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application
        android:theme="@style/AppTheme" >
    </application>
</manifest>

Referencia de Android

 0
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-03 19:46:58

Pruebe esta biblioteca, es ligera y fácil de implementar

Https://github.com/sunnag7/FontStyler

<com.sunnag.fontstyler.FontStylerView
              android:textStyle="bold"
              android:text="@string/about_us"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:paddingTop="8dp"
              app:fontName="Lato-Bold"
              android:textSize="18sp"
              android:id="@+id/textView64" />
 0
Author: Sanny Nagveker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-29 13:03:57

La respuesta es no, no puedes. Ver ¿Es posible establecer una fuente personalizada para toda la aplicación? para más información.

No Hay soluciones, pero nada en las líneas de "una sola línea de código aquí y todos mis fuentes será este en lugar de que".

(Doy las gracias a Google-y Apple - por eso). Las fuentes personalizadas tienen un lugar, pero haciéndolas fáciles de reemplazar en toda la aplicación, habrían creado todo un mundo de Comic Sans aplicaciones)

 -4
Author: Martin Marconcini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:29