Pregunta Cómo cambiar fontFamily of TextView en Android


Entonces me gustaría cambiar el android:fontFamily en Android, pero no veo ninguna fuente predefinida en Android. ¿Cómo selecciono uno de los predefinidos? Realmente no necesito definir mi propio TypeFace, pero todo lo que necesito es algo diferente de lo que muestra en este momento.

<TextView
    android:id="@+id/HeaderText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="52dp"
    android:gravity="center"
    android:text="CallerBlocker"
    android:textSize="40dp"
    android:fontFamily="Arial"
 />

¡Parece que lo que hice allí no funcionará realmente! Por cierto android:fontFamily="Arial" fue un intento estúpido!


600
2017-08-26 07:19


origen


Respuestas:


Desde Android 4.1 / 4.2 / 5.0, el siguiente Roboto familias de fuente están disponibles:

android:fontFamily="sans-serif"           // roboto regular
android:fontFamily="sans-serif-light"     // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-black"     // roboto black
android:fontFamily="sans-serif-thin"      // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium"    // roboto medium (android 5.0)

enter image description here

en combinación con

android:textStyle="normal|bold|italic"

estas 16 variantes son posibles:

  • Roboto regular
  • Roboto cursiva
  • Roboto negrita
  • Roboto negrita cursiva
  • Roboto-Light
  • Roboto-Light cursiva
  • Roboto-Thin
  • Roboto-Thin cursiva
  • Roboto-condensado
  • Roboto-Condensado en cursiva
  • Roboto-Condensed bold
  • Roboto-Condensado negrita cursiva
  • Roboto-Negro
  • Roboto-Black cursiva
  • Roboto-Medium
  • Roboto-Medium cursiva

fonts.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="font_family_light">sans-serif-light</string>
    <string name="font_family_medium">sans-serif-medium</string>
    <string name="font_family_regular">sans-serif</string>
    <string name="font_family_condensed">sans-serif-condensed</string>
    <string name="font_family_black">sans-serif-black</string>
    <string name="font_family_thin">sans-serif-thin</string>
</resources>

1473
2017-11-11 09:22



Esta es la manera de configurar la fuente mediante programación:

TextView tv = (TextView) findViewById(R.id.appname);
Typeface face = Typeface.createFromAsset(getAssets(),
            "fonts/epimodem.ttf");
tv.setTypeface(face);

pon el archivo de fuente en tu carpeta de activos. En mi caso, creé un subdirectorio llamado fuentes.

EDITAR: Si se pregunta dónde está su carpeta de activos, vea esta pregunta


154
2017-08-26 07:38



Tuve que analizar /system/etc/fonts.xml en un proyecto reciente. Estas son las familias de fuentes actuales a partir de Lollipop:

╔════╦════════════════════════════╦═════════════════════════════╗
║    ║ FONT FAMILY                ║ TTF FILE                    ║
╠════╬════════════════════════════╬═════════════════════════════╣
║  1 ║ casual                     ║ ComingSoon.ttf              ║
║  2 ║ cursive                    ║ DancingScript-Regular.ttf   ║
║  3 ║ monospace                  ║ DroidSansMono.ttf           ║
║  4 ║ sans-serif                 ║ Roboto-Regular.ttf          ║
║  5 ║ sans-serif-black           ║ Roboto-Black.ttf            ║
║  6 ║ sans-serif-condensed       ║ RobotoCondensed-Regular.ttf ║
║  7 ║ sans-serif-condensed-light ║ RobotoCondensed-Light.ttf   ║
║  8 ║ sans-serif-light           ║ Roboto-Light.ttf            ║
║  9 ║ sans-serif-medium          ║ Roboto-Medium.ttf           ║
║ 10 ║ sans-serif-smallcaps       ║ CarroisGothicSC-Regular.ttf ║
║ 11 ║ sans-serif-thin            ║ Roboto-Thin.ttf             ║
║ 12 ║ serif                      ║ NotoSerif-Regular.ttf       ║
║ 13 ║ serif-monospace            ║ CutiveMono.ttf              ║
╚════╩════════════════════════════╩═════════════════════════════╝

Aquí está el analizador sintáctico (basado en FontListParser)

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

/**
 * Helper class to get the current font families on an Android device.</p>
 * 
 * Usage:</p> {@code List<SystemFont> fonts = FontListParser.safelyGetSystemFonts();}</p>
 */
public final class FontListParser {

    private static final File FONTS_XML = new File("/system/etc/fonts.xml");

    private static final File SYSTEM_FONTS_XML = new File("/system/etc/system_fonts.xml");

    public static List<SystemFont> getSystemFonts() throws Exception {
        String fontsXml;
        if (FONTS_XML.exists()) {
            fontsXml = FONTS_XML.getAbsolutePath();
        } else if (SYSTEM_FONTS_XML.exists()) {
            fontsXml = SYSTEM_FONTS_XML.getAbsolutePath();
        } else {
            throw new RuntimeException("fonts.xml does not exist on this system");
        }
        Config parser = parse(new FileInputStream(fontsXml));
        List<SystemFont> fonts = new ArrayList<>();

        for (Family family : parser.families) {
            if (family.name != null) {
                Font font = null;
                for (Font f : family.fonts) {
                    font = f;
                    if (f.weight == 400) {
                        break;
                    }
                }
                SystemFont systemFont = new SystemFont(family.name, font.fontName);
                if (fonts.contains(systemFont)) {
                    continue;
                }
                fonts.add(new SystemFont(family.name, font.fontName));
            }
        }

        for (Alias alias : parser.aliases) {
            if (alias.name == null || alias.toName == null || alias.weight == 0) {
                continue;
            }
            for (Family family : parser.families) {
                if (family.name == null || !family.name.equals(alias.toName)) {
                    continue;
                }
                for (Font font : family.fonts) {
                    if (font.weight == alias.weight) {
                        fonts.add(new SystemFont(alias.name, font.fontName));
                        break;
                    }
                }
            }
        }

        if (fonts.isEmpty()) {
            throw new Exception("No system fonts found.");
        }

        Collections.sort(fonts, new Comparator<SystemFont>() {

            @Override
            public int compare(SystemFont font1, SystemFont font2) {
                return font1.name.compareToIgnoreCase(font2.name);
            }

        });

        return fonts;
    }

    public static List<SystemFont> safelyGetSystemFonts() {
        try {
            return getSystemFonts();
        } catch (Exception e) {
            String[][] defaultSystemFonts = {
                    {
                            "cursive", "DancingScript-Regular.ttf"
                    }, {
                            "monospace", "DroidSansMono.ttf"
                    }, {
                            "sans-serif", "Roboto-Regular.ttf"
                    }, {
                            "sans-serif-light", "Roboto-Light.ttf"
                    }, {
                            "sans-serif-medium", "Roboto-Medium.ttf"
                    }, {
                            "sans-serif-black", "Roboto-Black.ttf"
                    }, {
                            "sans-serif-condensed", "RobotoCondensed-Regular.ttf"
                    }, {
                            "sans-serif-thin", "Roboto-Thin.ttf"
                    }, {
                            "serif", "NotoSerif-Regular.ttf"
                    }
            };
            List<SystemFont> fonts = new ArrayList<>();
            for (String[] names : defaultSystemFonts) {
                File file = new File("/system/fonts", names[1]);
                if (file.exists()) {
                    fonts.add(new SystemFont(names[0], file.getAbsolutePath()));
                }
            }
            return fonts;
        }
    }

    /* Parse fallback list (no names) */
    public static Config parse(InputStream in) throws XmlPullParserException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(in, null);
            parser.nextTag();
            return readFamilies(parser);
        } finally {
            in.close();
        }
    }

    private static Alias readAlias(XmlPullParser parser) throws XmlPullParserException, IOException {
        Alias alias = new Alias();
        alias.name = parser.getAttributeValue(null, "name");
        alias.toName = parser.getAttributeValue(null, "to");
        String weightStr = parser.getAttributeValue(null, "weight");
        if (weightStr == null) {
            alias.weight = 0;
        } else {
            alias.weight = Integer.parseInt(weightStr);
        }
        skip(parser); // alias tag is empty, ignore any contents and consume end tag
        return alias;
    }

    private static Config readFamilies(XmlPullParser parser) throws XmlPullParserException,
            IOException {
        Config config = new Config();
        parser.require(XmlPullParser.START_TAG, null, "familyset");
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            if (parser.getName().equals("family")) {
                config.families.add(readFamily(parser));
            } else if (parser.getName().equals("alias")) {
                config.aliases.add(readAlias(parser));
            } else {
                skip(parser);
            }
        }
        return config;
    }

    private static Family readFamily(XmlPullParser parser) throws XmlPullParserException,
            IOException {
        String name = parser.getAttributeValue(null, "name");
        String lang = parser.getAttributeValue(null, "lang");
        String variant = parser.getAttributeValue(null, "variant");
        List<Font> fonts = new ArrayList<Font>();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            String tag = parser.getName();
            if (tag.equals("font")) {
                String weightStr = parser.getAttributeValue(null, "weight");
                int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
                boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
                String filename = parser.nextText();
                String fullFilename = "/system/fonts/" + filename;
                fonts.add(new Font(fullFilename, weight, isItalic));
            } else {
                skip(parser);
            }
        }
        return new Family(name, fonts, lang, variant);
    }

    private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
        int depth = 1;
        while (depth > 0) {
            switch (parser.next()) {
            case XmlPullParser.START_TAG:
                depth++;
                break;
            case XmlPullParser.END_TAG:
                depth--;
                break;
            }
        }
    }

    private FontListParser() {

    }

    public static class Alias {

        public String name;

        public String toName;

        public int weight;
    }

    public static class Config {

        public List<Alias> aliases;

        public List<Family> families;

        Config() {
            families = new ArrayList<Family>();
            aliases = new ArrayList<Alias>();
        }

    }

    public static class Family {

        public List<Font> fonts;

        public String lang;

        public String name;

        public String variant;

        public Family(String name, List<Font> fonts, String lang, String variant) {
            this.name = name;
            this.fonts = fonts;
            this.lang = lang;
            this.variant = variant;
        }

    }

    public static class Font {

        public String fontName;

        public boolean isItalic;

        public int weight;

        Font(String fontName, int weight, boolean isItalic) {
            this.fontName = fontName;
            this.weight = weight;
            this.isItalic = isItalic;
        }

    }

    public static class SystemFont {

        public String name;

        public String path;

        public SystemFont(String name, String path) {
            this.name = name;
            this.path = path;
        }

    }
}

Siéntase libre de usar la clase de arriba en su proyecto. Por ejemplo, podría proporcionar a los usuarios una selección de familias de fuentes y establecer el tipo de letra en función de sus preferencias.

Un pequeño ejemplo incompleto:

final List<FontListParser.SystemFont> fonts = FontListParser.safelyGetSystemFonts();
String[] items = new String[fonts.size()];
for (int i = 0; i < fonts.size(); i++) {
    items[i] = fonts.get(i).name;
}

new AlertDialog.Builder(this).setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        FontListParser.SystemFont selectedFont = fonts.get(which);
        // TODO: do something with the font
        Toast.makeText(getApplicationContext(), selectedFont.path, Toast.LENGTH_LONG).show();
    }
}).show();

82
2018-04-09 08:38



Empezando desde Android-Studio 3.0  es muy fácil cambiar la familia de fuentes

Al usar la biblioteca de soporte 26, funcionará en dispositivos que ejecuten Android API versión 16 y superior.

Crea una carpeta font debajo res directorio. Descargue la fuente que quiera y péguela dentro font carpeta. La estructura debería ser algo como abajo

Here

ahora puedes cambiar la fuente en diseño utilizando

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/dancing_script"/>

Cambiar Programaticamente

 Typeface typeface = getResources().getFont(R.font.myfont);
 textView.setTypeface(typeface);  

Para cambiar la fuente usando styles.xml crea un estilo

 <style name="Regular">
        <item name="android:fontFamily">@font/dancing_script</item>
        <item name="android:textStyle">normal</item>
 </style>

y aplica este estilo a TextView

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    style="@style/Regular"/>

Tu también puedes crear el tuyo Familia tipográfica

- Haga clic derecho en la carpeta de fuente y vaya a Nuevo> Archivo de recursos de fuentes. Aparece la ventana Nuevo archivo de recursos.

- Introducir el nombre del archivo, y luego click DE ACUERDO. El nuevo XML de recurso de fuente se abre en el editor.

Escriba aquí su propia familia de fuentes, por ejemplo

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

esto es simplemente un mapeo de un fontStyle y fontWeight específicos al recurso de fuente que se usará para representar esa variante específica. Los valores válidos para fontStyle son normales o cursiva; y fontWeight se ajusta a la Especificación de peso de fuente CSS 

1. A cambio fontfamily en diseño puedes escribir

 <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/lobster"/>

2. Cambiar Programáticamente

 Typeface typeface = getResources().getFont(R.font.myfont);
   //or to support all versions use
Typeface typeface = ResourcesCompat.getFont(context, R.font.myfont);
 textView.setTypeface(typeface);  

Nota: A partir de Android Support Library 26.0, debe declarar ambos conjuntos de atributos (android: y app:) para garantizar que las fuentes se carguen en los dispositivos que se ejecutan  Api 26 o inferior.

  <?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto">
    <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/myfont-Regular"
          app:fontStyle="normal" app:fontWeight="400" app:font="@font/myfont-Regular"/>
    <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/myfont-Italic"
          app:fontStyle="italic" app:fontWeight="400" app:font="@font/myfont-Italic" />
</font-family>

Para cambiar la fuente de toda la aplicación Agregue estas dos líneas en AppTheme

 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:fontFamily">@font/your_font</item>
     <item name="fontFamily">@font/your_font</item>
  </style>

Ver el Documentación , Tutorial de fuentes personalizadas de Android Para más información


52
2018-03-23 12:51



Android no permite establecer fuentes personalizadas desde el diseño XML. En su lugar, debe agrupar el archivo de fuente específico en la carpeta de activos de su aplicación y configurarlo mediante programación. Algo como:

TextView textView = (TextView) findViewById(<your TextView ID>);
Typeface typeFace = Typeface.createFromAsset(getAssets(), "<file name>");
textView.setTypeface(typeFace);

Tenga en cuenta que solo puede ejecutar este código después de llamar a setContentView (). Además, solo algunas fuentes son compatibles con Android, y deben estar en una .ttf (TrueType) o .otf (OpenType) formato. Incluso entonces, algunas fuentes pueden no funcionar.

Esta es una fuente que definitivamente funciona en Android, y puedes usar esto para confirmar que tu código está funcionando en caso de que tu archivo de fuente no sea compatible con Android.

Actualización de Android O: ahora esto es posible con XML en Android O, basado en el comentario de Roger.


41
2017-08-26 07:42



Es lo mismo que android:typeface.

las fuentes incorporadas son:

  • normal
  • sin
  • serif
  • monospace

Ver android: tipo de letra.


24
2017-08-26 07:41



Para configurar Roboto mediante programación:

paint.setTypeface(Typeface.create("sans-serif-thin", Typeface.NORMAL));

22
2017-08-06 22:59



Si lo quiere programaticamente, puede usar

label.setTypeface(Typeface.SANS_SERIF, Typeface.ITALIC);

Dónde SANS_SERIF puedes usar:

  • DEFAULT
  • DEFAULT_BOLD
  • MONOSPACE
  • SANS_SERIF
  • SERIF

Y donde ITALIC puedes usar:

  • BOLD
  • BOLD_ITALIC
  • ITALIC
  • NORMAL

Todo está dicho en los desarrolladores de Android


18
2017-10-03 19:21



Estoy usando una excelente biblioteca Caligrafía por Chris Jenx diseñado para permitirle usar fuentes personalizadas en su aplicación de Android. ¡Darle una oportunidad!


14
2017-07-06 13:50



Lo que quieres no es posible. Debes necesitar establecer TypeFace en tu Código.

En XML lo que puedes hacer es

android:typeface="sans" | "serif" | "monospace"

Aparte de esto, no puedes jugar mucho con las Fuentes en XML. :)

por Arial necesitas configurar el tipo de letra en tu código.


11
2017-08-26 07:38