¿Cómo cambiar la fuente en TextView?

Respuestas:

342

Primero, el valor predeterminado no es Arial. El valor predeterminado es Droid Sans.

En segundo lugar, para cambiar a una fuente incorporada diferente, úsela android:typefaceen el diseño XML o setTypeface()en Java.

En tercer lugar, no hay fuente Helvetica en Android. Las opciones integradas son Droid Sans ( sans), Droid Sans Mono ( monospace) y Droid Serif ( serif). Si bien puede agrupar sus propias fuentes con su aplicación y usarlas a través de setTypeface(), tenga en cuenta que los archivos de fuentes son grandes y, en algunos casos, requieren acuerdos de licencia (por ejemplo, Helvetica, una fuente Linotype ).

EDITAR

El lenguaje de diseño de Android se basa en herramientas tipográficas tradicionales como escala, espacio, ritmo y alineación con una cuadrícula subyacente. La implementación exitosa de estas herramientas es esencial para ayudar a los usuarios a comprender rápidamente una pantalla de información. Para soportar tal uso de la tipografía, Ice Cream Sandwich introdujo una nueva familia de tipos llamada Roboto, creada específicamente para los requisitos de IU y pantallas de alta resolución.

El marco actual de TextView ofrece Roboto en pesos delgados, ligeros, regulares y en negrita, junto con un estilo en cursiva para cada peso. El marco también ofrece la variante Roboto Condensed en pesos regulares y en negrita, junto con un estilo en cursiva para cada peso.

Después de ICS, Android incluye el estilo de fuente Roboto, Leer más Roboto

EDITAR 2

Con la llegada de Support Library 26, Android ahora admite fuentes personalizadas de forma predeterminada. Puede insertar nuevas fuentes en res / fonts que se pueden establecer en TextViews individualmente en XML o mediante programación. La fuente predeterminada para toda la aplicación también se puede cambiar definiéndola styles.xml La documentación del desarrollador de Android tiene una guía clara sobre esto aquí

CommonsWare
fuente
66
¿No hay forma de configurar fuentes en XML? ¿Por qué?
Jonny
55
@ Jonny En realidad puedes. Estás creando una clase que extiende TextView y llama a setTypeface desde el constructor.
Mark Phillip
¿Cómo hacerlo en diseño XML?
M. Usman Khan
2
@usman: Necesitaría una biblioteca de terceros, como Caligrafía: github.com/chrisjenx/Calligraphy
CommonsWare
Establecer el tipo de letra usando el código java es difícil debido a múltiples líneas, he creado una biblioteca para configurar fuentes personalizadas. Puede encontrar el uso de una biblioteca en esta respuesta stackoverflow.com/a/42001474/4446392
Chathura Jayanath
254

Primero descargue el .ttfarchivo de la fuente que necesita ( arial.ttf). Colóquelo en la assets carpeta. (Dentro de la carpeta de activos cree una nueva carpeta llamada fuentes y colóquela dentro de ella.) Use el siguiente código para aplicar la fuente a su TextView:

Typeface type = Typeface.createFromAsset(getAssets(),"fonts/arial.ttf"); 
textView.setTypeface(type);
HjK
fuente
Estimado Mayur, ¿Alguna recomendación sobre dónde obtener estos archivos .ttf?
lonelearner
3
Estimado @lonelearner, puede descargar archivos de fuentes gratuitas (.ttf) en 1001freefonts.com o simplemente google "Fuentes gratuitas"
ymerdrengene
10
Para aquellos que usan Android Studio y no pueden encontrar una carpeta de "activos", vea esta pregunta . Respuesta corta: src/main/assets/fonts/.
adamdport
51
Typeface tf = Typeface.createFromAsset(getAssets(),
        "fonts/DroidSansFallback.ttf");
TextView tv = (TextView) findViewById(R.id.CustomFontText);
tv.setTypeface(tf);
Android Girl
fuente
33

Es posible que desee crear clase estática que contendrá todas las fuentes. De esa manera, no creará la fuente varias veces, lo que podría afectar negativamente el rendimiento . Solo asegúrese de crear una subcarpeta llamada " fuentes " en la carpeta " activos ".

Haz algo como:

public class CustomFontsLoader {

public static final int FONT_NAME_1 =   0;
public static final int FONT_NAME_2 =   1;
public static final int FONT_NAME_3 =   2;

private static final int NUM_OF_CUSTOM_FONTS = 3;

private static boolean fontsLoaded = false;

private static Typeface[] fonts = new Typeface[3];

private static String[] fontPath = {
    "fonts/FONT_NAME_1.ttf",
    "fonts/FONT_NAME_2.ttf",
    "fonts/FONT_NAME_3.ttf"
};


/**
 * Returns a loaded custom font based on it's identifier. 
 * 
 * @param context - the current context
 * @param fontIdentifier = the identifier of the requested font
 * 
 * @return Typeface object of the requested font.
 */
public static Typeface getTypeface(Context context, int fontIdentifier) {
    if (!fontsLoaded) {
        loadFonts(context);
    }
    return fonts[fontIdentifier];
}


private static void loadFonts(Context context) {
    for (int i = 0; i < NUM_OF_CUSTOM_FONTS; i++) {
        fonts[i] = Typeface.createFromAsset(context.getAssets(), fontPath[i]);
    }
    fontsLoaded = true;

}
}

De esta manera, puede obtener la fuente desde cualquier lugar de su aplicación.

Daniel L.
fuente
1
Tipo impresionante! Esta es la belleza de OOP. ¡Buen trabajo! :)
Joshua Michael Waggoner
¿Cómo uso esta clase?
Jack
Debe colocar este código en su proyecto, adaptarlo a sus fuentes y luego usar el método estático getTypeface (..) desde cualquier lugar de su aplicación.
Daniel L.
Utilicé una solución similar, pero agregué el almacenamiento en caché para mejorar el rendimiento ... en cualquier caso, ¿se encontró con una situación en la que la fuente funciona en algunos teléfonos y no en otros?
RJFares
20

La mejor práctica de todas

TextViewPlus.java:

public class TextViewPlus extends TextView {
    private static final String TAG = "TextView";

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

    public TextViewPlus(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomFont(context, attrs);
    }

    public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomFont(context, attrs);
    }

    private void setCustomFont(Context ctx, AttributeSet attrs) {
        TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.TextViewPlus);
        String customFont = a.getString(R.styleable.TextViewPlus_customFont);
        setCustomFont(ctx, customFont);
        a.recycle();
    }

    public boolean setCustomFont(Context ctx, String asset) {
        Typeface typeface = null;
        try {
            typeface = Typeface.createFromAsset(ctx.getAssets(), asset);
        } catch (Exception e) {
            Log.e(TAG, "Unable to load typeface: "+e.getMessage());
            return false;
        }

        setTypeface(typeface);
        return true;
    }
}

attrs.xml: (Dónde colocar res / valores )

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="TextViewPlus">
        <attr name="customFont" format="string"/>
    </declare-styleable>
</resources>

Cómo utilizar:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:foo="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.mypackage.TextViewPlus
        android:id="@+id/textViewPlus1"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:text="@string/showingOffTheNewTypeface"
        foo:customFont="my_font_name_regular.otf">
    </com.mypackage.TextViewPlus>
</LinearLayout>

Espero que esto te ayudará.

Hiren Patel
fuente
1
¿Por qué subclasificar TextView es la mejor práctica?
Stealth Rabbi
@Stealth Rabbi, aquí solo podemos pasar la fuente personalizada por xml, no es necesario escribir código java especial para cada vista de texto.
Hiren Patel
Hay una biblioteca para eso. Simplemente agregue su fuente en la carpeta de activos y declare en XML. github.com/febaisi/CustomTextView
febaisi
Su biblioteca se ve bien, pero el único problema es que es para Android 21+
loloof64
@febaisi como vi en su ejemplo de lib raw.githubusercontent.com/febaisi/CustomTextView/master/wiki/…
Mr.Q
17

Las respuestas anteriores son correctas. Solo asegúrese de crear una subcarpeta llamada "fuentes" en la carpeta "activos" si está usando ese código.

VJ Vélan Solutions
fuente
1
Tu comentario es redundante. La explicación anterior dice exactamente lo que dijiste, y más ...
Joshua Michael Waggoner
14

Otra forma de consolidar la creación de fuentes ...

public class Font {
  public static final Font  PROXIMA_NOVA    = new Font("ProximaNovaRegular.otf");
  public static final Font  FRANKLIN_GOTHIC = new Font("FranklinGothicURWBoo.ttf");
  private final String      assetName;
  private volatile Typeface typeface;

  private Font(String assetName) {
    this.assetName = assetName;
  }

  public void apply(Context context, TextView textView) {
    if (typeface == null) {
      synchronized (this) {
        if (typeface == null) {
          typeface = Typeface.createFromAsset(context.getAssets(), assetName);
        }
      }
    }
    textView.setTypeface(typeface);
  }
}

Y luego para usar en tu actividad ...

myTextView = (TextView) findViewById(R.id.myTextView);
Font.PROXIMA_NOVA.apply(this, myTextView);

Eso sí, este idioma de bloqueo de doble verificación con el campo volátil solo funciona correctamente con el modelo de memoria utilizado en Java 1.5+.

Chris Aitchison
fuente
¿Por qué esta respuesta solo tiene 1 voto a favor y el anterior tiene 15? ¿Qué hace al otro mejor? Me parece que este es el más sencillo usando el principio singleton ...?
Koen Demonie
Acabo de ver que tienes tu constructor público, lo haría privado ya que no necesitas ningún acceso a él. Estás utilizando tus fuentes internas de todos modos ...
Koen Demonie
Absolutamente debe ser constructor privado. Bien visto :) Se editará!
Chris Aitchison
12

La mejor práctica es usar la biblioteca de soporte de Android versión 26.0.0 o superior.

PASO 1: agregue el archivo de fuente

  1. En la carpeta res crea una nueva fuente diccionario de recursos de
  2. Agregar archivo de fuente ( .ttf , .orf )

Por ejemplo, cuando el archivo de fuente será helvetica_neue.ttf eso generará R.font.helvetica_neue

PASO 2: crear familia de fuentes

  1. En la carpeta de fuentes, agregue un nuevo archivo de recursos
  2. Incluya cada archivo de fuente, estilo y atributo de peso en el elemento.

Por ejemplo:

<?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/helvetica_neue" />
</font-family>

PASO 3: úsalo

En diseños xml:

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

O agregue fuentes al estilo:

<style name="customfontstyle" parent="@android:style/TextAppearance.Small">
    <item name="android:fontFamily">@font/lobster</item>
</style>

Para obtener más ejemplos, puede seguir la documentación:

Trabajando con fuentes

Marek Rzeźniczek
fuente
7

Es un poco viejo, pero mejoré un poco la clase CustomFontLoader y quería compartirlo para que pueda ser útil. Simplemente cree una nueva clase con este código.

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

public enum FontLoader {

ARIAL("arial"),
TIMES("times"),
VERDANA("verdana"),
TREBUCHET("trbuchet"),
GEORGIA("georgia"),
GENEVA("geneva"),
SANS("sans"),
COURIER("courier"),
TAHOMA("tahoma"),
LUCIDA("lucida");   


private final String name;
private Typeface typeFace;


private FontLoader(final String name) {
    this.name = name;

    typeFace=null;  
}

public static Typeface getTypeFace(Context context,String name){
    try {
        FontLoader item=FontLoader.valueOf(name.toUpperCase(Locale.getDefault()));
        if(item.typeFace==null){                
            item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");                 
        }           
        return item.typeFace;
    } catch (Exception e) {         
        return null;
    }                   
}
public static Typeface getTypeFace(Context context,int id){
    FontLoader myArray[]= FontLoader.values();
    if(!(id<myArray.length)){           
        return null;
    } 
    try {
        if(myArray[id].typeFace==null){     
            myArray[id].typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+myArray[id].name+".ttf");                       
        }       
        return myArray[id].typeFace;    
    }catch (Exception e) {          
        return null;
    }   

}

public static Typeface getTypeFaceByName(Context context,String name){      
    for(FontLoader item: FontLoader.values()){              
        if(name.equalsIgnoreCase(item.name)){
            if(item.typeFace==null){
                try{
                    item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
                }catch (Exception e) {          
                    return null;
                }   
            }
            return item.typeFace;
        }               
    }
    return null;
}   

public static void loadAllFonts(Context context){       
    for(FontLoader item: FontLoader.values()){              
        if(item.typeFace==null){
            try{
                item.typeFace=Typeface.createFromAsset(context.getAssets(), "fonts/"+item.name+".ttf");     
            }catch (Exception e) {
                item.typeFace=null;
            }   
        }                
    }       
}   
}

Luego use este código en su vista de texto:

 Typeface typeFace=FontLoader.getTypeFace(context,"arial");  
 if(typeFace!=null) myTextView.setTypeface(typeFace);
Alan
fuente
5

Finalmente obtuve una solución muy fácil para esto.

  1. use estas bibliotecas de soporte en el nivel de aplicación gradle ,

    compile 'com.android.support:appcompat-v7:26.0.2'
    compile 'com.android.support:support-v4:26.0.2'
  2. luego cree un directorio llamado "fuente" dentro de la carpeta res

  3. coloque los archivos de fuentes (ttf) en ese directorio de fuentes, tenga en cuenta las convenciones de nomenclatura [por ejemplo, nombre no debe contener ningún carácter especial, ningún carácter en mayúscula y ningún espacio o tabulación]
  4. Después de eso, haga referencia a esa fuente de xml como esta

            <Button
            android:id="@+id/btn_choose_employee"
            android:layout_width="140dp"
            android:layout_height="40dp"
            android:layout_centerInParent="true"
            android:background="@drawable/rounded_red_btn"
            android:onClick="btnEmployeeClickedAction"
            android:text="@string/searching_jobs"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:fontFamily="@font/times_new_roman_test"
            />

En este ejemplo, times_new_roman_test es un archivo ttf de fuentes de ese directorio de fuentes

Shamsul Arefin Sajib
fuente
4
import java.lang.ref.WeakReference;
import java.util.HashMap;

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

public class FontsManager {

    private static FontsManager instance;

    private static HashMap<String, WeakReference<Typeface>> typefaces = new HashMap<String, WeakReference<Typeface>>();

    private static Context context;

    private FontsManager(final Context ctx) {
        if (context == null) {
            context = ctx;
        }
    }

    public static FontsManager getInstance(final Context appContext) {
        if (instance == null) {
            instance = new FontsManager(appContext);
        }
        return instance;
    }

    public static FontsManager getInstance() {
        if (instance == null) {
            throw new RuntimeException(
                    "Call getInstance(Context context) at least once to init the singleton properly");
        }
        return instance;
    }

    public Typeface getFont(final String assetName) {
        final WeakReference<Typeface> tfReference = typefaces.get(assetName);
        if (tfReference == null || tfReference.get() == null) {
            final Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(),
                    assetName);
            typefaces.put(assetName, new WeakReference<Typeface>(tf));
            return tf;
        }
        return tfReference.get();
    }

}

De esta manera, puede crear una Vista que herede de TextView y llame a setTypeface en su constructor.

Charlie-Blake
fuente
1
Hola, ¿por qué usas WeakReference para contener el objeto TypeFace?
Lazy
3

Cuando su fuente se almacena en el interior, res/asset/fonts/Helvetica.ttfuse lo siguiente:

Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/Helvetica.ttf"); 
txt.setTypeface(tf);

O, si su archivo de fuente está almacenado dentro, res/font/helvetica.ttfuse lo siguiente:

Typeface tf = ResourcesCompat.getFont(this,R.font.helvetica);
txt.setTypeface(tf);
Pankaj Lilan
fuente
2
¡Gracias, estábamos buscando la parte donde la tenía en la carpeta res!
Mikkel Larsen
2

obtener la fuente del activo y configurarla para todos los niños

public static 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(Typeface.createFromAsset(context.getAssets(),"DroidNaskh.ttf"));// "BKOODB.TTF"));
        }
    } catch (Exception e) {
 }
 } 
Manian Rezaee
fuente
2
  1. agregar clase FontTextView.java:


public class FontTextView extends TextView {
    String fonts[] = {"HelveticaNeue.ttf", "HelveticaNeueLight.ttf", "motschcc.ttf", "symbol.ttf"};

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

    public FontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (!isInEditMode()) {
            init(attrs);
        }

    }

    public FontTextView(Context context) {
        super(context);
        if (!isInEditMode()) {
            init(null);
        }
    }

    private void init(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontTextView);
            if (a.getString(R.styleable.FontTextView_font_type) != null) {
                String fontName = fonts[Integer.valueOf(a.getString(R.styleable.FontTextView_font_type))];

                if (fontName != null) {
                    Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/" + fontName);
                    setTypeface(myTypeface);
                }
                a.recycle();
            }
        }
    }
}


  1. agregar a la fuente de la biblioteca de activos
    ingrese la descripción de la imagen aquí


  1. agregar a attrs.xml, los números deben estar en el orden en la clase de matriz.

    <declare-styleable name="FontTextView">
    <attr name="font_type" format="enum">
        <enum name="HelveticaNeue" value="0"/>
        <enum name="HelveticaNeueLight" value="1"/>
        <enum name="motschcc" value="2"/>
        <enum name="symbol" value="3"/>
    </attr>


  1. Seleccione una fuente de la lista
    ingrese la descripción de la imagen aquí
david
fuente
¿Necesita crear una instancia de esta clase en MainActivity? Porque no está cambiando nada para mí.
Tobias Mayr
1

Android usa la fuente Roboto, que es una fuente muy bonita, con varios pesos diferentes (regular, ligero, delgado, condensado) que se ven muy bien en pantallas de alta densidad.

Verifique el siguiente enlace para verificar las fuentes roboto:

Cómo usar Roboto en diseño xml

Volviendo a su pregunta, si desea cambiar la fuente de todos los TextView / Button en su aplicación , intente agregar el siguiente código en su styles.xml para usar la fuente Roboto-light :

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    ......
    <item name="android:buttonStyle">@style/MyButton</item>
    <item name="android:textViewStyle">@style/MyTextView</item>
</style>

<style name="MyButton" parent="@style/Widget.AppCompat.Button">
    <item name="android:textAllCaps">false</item>
    <item name="android:fontFamily">sans-serif-light</item>
</style>

<style name="MyTextView" parent="@style/TextAppearance.AppCompat">
    <item name="android:fontFamily">sans-serif-light</item>
</style>

Y no olvides usar 'AppTheme' en tu AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ......
</application>
Velero
fuente
0

Quizás algo un poco más simple:

public class Fonts {
  public static HashSet<String,Typeface> fonts = new HashSet<>();

  public static Typeface get(Context context, String file) {
    if (! fonts.contains(file)) {
      synchronized (this) {
        Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
        fonts.put(name, typeface);
      }
    }
    return fonts.get(file);
  }
}

// Usage
Typeface myFont = Fonts.get("arial.ttf");

(Tenga en cuenta que este código no se ha probado, pero en general este enfoque debería funcionar bien).

trans
fuente