Android: uso de fuentes personalizadas


266

Apliqué una fuente personalizada a una TextView, pero no parece cambiar el tipo de letra.

Aquí está mi código:

    Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
    TextView myTextView = (TextView)findViewById(R.id.myTextView);
    myTextView.setTypeface(myTypeface);

¿Alguien puede sacarme de este problema?


1
Hay un error en su sintaxis, debería sermyTextView.setTypeface(myTypeface);
yuttadhammo




Aquí tiene una manera eficiente de cambiar la fuente para toda la aplicación: stackoverflow.com/questions/18847531/…
Diego Palomar

Respuestas:


230

En Mobiletuts + hay un tutorial muy bueno sobre el formato de texto para Android. Consejo rápido: personaliza las fuentes de Android

EDITAR: Lo probé yo mismo ahora. Aquí está la solución. Puede usar una subcarpeta llamada fuentes, pero debe ir en la assetscarpeta, no en la rescarpeta. Entonces

activos / fuentes

También asegúrese de que el final de la fuente me refiero al final del archivo de la fuente en minúsculas. En otras palabras, no debería ser así, myFont.TTFpero de myfont.ttf esta manera debe ser en minúsculas


Edité mi respuesta con la solución ahora.
Octavian A. Damiean

¿Podría enviarme algún proyecto de demostración en funcionamiento? He intentado en la carpeta assets / fonts / xyz.ttf y assets / xyz.ttf pero no toma esa fuente. Muestra solo la fuente predeterminada ...
RATTLESNAKE

2
Claro que aquí está el enlace al proyecto comprimido. dl.dropbox.com/u/8288893/customFont.zip
Octavian A. Damiean

55
Si sigue este tutorial, asegúrese de utilizar la ruta Typeface.createFromAsset (getAssets (), "fonts / yourfont.ttf"); si lo ha puesto en el subdirectorio de fuentes
Jameo

no incluya "assets /" en el nombre del archivo (porque la createFromAssetfunción apunta directamente dentro del assetsdirectorio)
topher

55

Después de probar la mayoría de las soluciones descritas en este hilo, encontré accidentalmente Caligrafía ( https://github.com/chrisjenx/Calligraphy ), una biblioteca de Christopher Jenkins que le permite agregar fácilmente fuentes personalizadas a su aplicación. Las ventajas de su lib en comparación con los enfoques sugeridos aquí son:

  1. no tiene que presentar su propio componente de vista de texto anulado, usa TextView incorporado
  2. puedes incluir fácilmente la biblioteca usando gradle
  3. La biblioteca no limita su elección de fuentes; solo agrega sus preferidos al directorio de activos
  4. no solo obtiene vistas de texto personalizadas, todos los demás componentes de Android basados ​​en texto también se mostrarán usando su fuente personalizada.

1
cuál es el tamaño de esa biblioteca es una pregunta importante, porque eso afectará el tamaño de la aplicación.
eRaisedToX

32

Sé que ya hay buenas respuestas, pero aquí hay una implementación totalmente funcional.

Aquí está la vista de texto personalizado:

package com.mycompany.myapp.widget;

/**
 * Text view with a custom font.
 * <p/>
 * In the XML, use something like {@code customAttrs:customFont="roboto-thin"}. The list of fonts
 * that are currently supported are defined in the enum {@link CustomFont}. Remember to also add
 * {@code xmlns:customAttrs="http://schemas.android.com/apk/res-auto"} in the header.
 */
public class CustomFontTextView extends TextView {

    private static final String sScheme =
            "http://schemas.android.com/apk/res-auto";
    private static final String sAttribute = "customFont";

    static enum CustomFont {
        ROBOTO_THIN("fonts/Roboto-Thin.ttf"),
        ROBOTO_LIGHT("fonts/Roboto-Light.ttf");

        private final String fileName;

        CustomFont(String fileName) {
            this.fileName = fileName;
        }

        static CustomFont fromString(String fontName) {
            return CustomFont.valueOf(fontName.toUpperCase(Locale.US));
        }

        public Typeface asTypeface(Context context) {
            return Typeface.createFromAsset(context.getAssets(), fileName);
        }
    }

    public CustomFontTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (isInEditMode()) {
            return;
        } else {
            final String fontName = attrs.getAttributeValue(sScheme, sAttribute);

            if (fontName == null) {
                throw new IllegalArgumentException("You must provide \"" + sAttribute + "\" for your text view");
            } else {
                final Typeface customTypeface = CustomFont.fromString(fontName).asTypeface(context);
                setTypeface(customTypeface);
            }
        }
    }
}

Aquí están los atributos personalizados. Esto debería ir a su res/attrs.xmlarchivo:

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

Y así es como lo usas. Usaré un diseño relativo para envolverlo y mostrar la customAttrdeclaración, pero obviamente podría ser cualquier diseño que ya tenga.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:customAttrs="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.mycompany.myapp.widget.CustomFontTextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="foobar"
         customAttrs:customFont="roboto_thin" />

</RelativeLayout>

¿A qué se customAttrsrefiere en mi proyecto?
Skynet

@Skynet se refiere al espacio de nombres definido en su vista raíz que es xmlns:customAttrs="http://schemas.android.com/apk/res-auto". Esto obtiene automáticamente los atributos establecidos para vistas personalizadas. En este caso, tiene un atributo llamado customFont definido en attrs.xml. Una forma más fácil de entender es observar xmlns:android="http://schemas.android.com/apk/res/android"qué define el espacio de nombres para sus atributos de Android. Entonces, si cambiaste eso a, aentonces en lugar de android:texteso sería a:text.
CodyEngel

14

He usado esto con éxito antes. La única diferencia entre nuestras implementaciones es que no estaba usando una subcarpeta en activos. Sin embargo, no estoy seguro de si eso cambiará algo.


13

Siempre que haya colocado la fuente en el lugar correcto y no haya ningún error en el archivo de fuente, su código debería funcionar así, RATTLESNAKE.

Sin embargo, sería mucho más fácil si pudieras definir una fuente en tu diseño xml, así:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <!-- This text view is styled with the app theme -->
    <com.innovattic.font.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This uses my font in bold italic style" />

    <!-- This text view is styled here and overrides the app theme -->
    <com.innovattic.font.FontTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:flFont="anotherFont"
        android:textStyle="normal"
        android:text="This uses another font in normal style" />

    <!-- This text view is styled with a style and overrides the app theme -->
    <com.innovattic.font.FontTextView
        style="@style/StylishFont"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This also uses another font in normal style" />

</LinearLayout>

Con el acompañamiento res/values/styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">

    <!-- Application theme -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <item name="android:textViewStyle">@style/MyTextViewStyle</item>
    </style>

    <!-- Style to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextViewStyle" parent="@android:style/Widget.Holo.Light.TextView">
        <item name="android:textAppearance">@style/MyTextAppearance</item>
    </style>

    <!-- Text appearance to use for ALL text views (including FontTextView) -->
    <!-- Use a different parent if you don't want Holo Light -->
    <style name="MyTextAppearance" parent="@android:style/TextAppearance.Holo">
        <!-- Alternatively, reference this font with the name "aspergit" -->
        <!-- Note that only our own TextView's will use the font attribute -->
        <item name="flFont">someFont</item>
        <item name="android:textStyle">bold|italic</item>
    </style>

    <!-- Alternative style, maybe for some other widget -->
    <style name="StylishFont">
        <item name="flFont">anotherFont</item>
        <item name="android:textStyle">normal</item>
    </style>

</resources>

Creé un par de herramientas específicamente para este propósito. Consulte este proyecto desde GitHub, o eche un vistazo a esta publicación de blog que explica todo.


13

La mejor manera de hacerlo Desde la versión de vista previa de Android O es de esta manera:

funciona solo si tiene Android Studio-2.4 o superior

  1. Haga clic derecho en la carpeta res y vaya a Nuevo> directorio de recursos de Android .
    Aparece la ventana Nuevo directorio de recursos.
  2. En la lista Tipo de recurso, seleccione fuente y luego haga clic en Aceptar.
  3. Añadir sus ficheros en la carpeta de fuentes estructura de carpetas debajo .El genera R.font.dancing_script, R.font.la_lay R.font.ba_ba.
  4. Haga doble clic en un archivo de fuente para obtener una vista previa de las fuentes del archivo en el editor.

A continuación debemos crear una familia de fuentes:

  1. 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.
  2. Ingrese el nombre del archivo y luego haga clic en Aceptar . El nuevo recurso XML de fuente se abre en el editor.
  3. Incluya cada archivo de fuente, estilo y atributo de peso en el elemento de etiqueta de fuente. El siguiente XML ilustra la adición de atributos relacionados con la fuente en el recurso XML de fuente:

Agregar fuentes a un TextView:

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

A partir de la documentación

Trabajando con fuentes

Todos los pasos son correctos.


44
oni api> 26 ((
maXp


A este le falta un gran paso # 3 ... ¿Cómo haces eso?
Código Wiget

12

Para las fuentes personalizadas en Android, cree una carpeta dentro de la carpeta de activos.

Si extiende UIBaseFragment:

Typeface font = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Arial.ttf");
        tv.setTypeface(font);

más si extiende la actividad:

Typeface font = Typeface.createFromAsset(getContext().getAssets(), "fonts/Arial.ttf");
        tv.setTypeface(font);

7

Puede usar PixlUI en https://github.com/neopixl/PixlUI

importar su .jar y usarlo en XML

 <com.neopixl.pixlui.components.textview.TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world"
    pixlui:typeface="GearedSlab.ttf" />

4

Como no estaba satisfecho con todas las soluciones presentadas en SO, se me ocurrió la mía. Se basa en un pequeño truco con etiquetas (es decir, no puede usar etiquetas en su código), puse la ruta de la fuente allí. Entonces, al definir vistas, puede hacer esto:

<TextView
        android:id="@+id/textViewHello1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World 1"
        android:tag="fonts/Oswald-Regular.ttf"/>

o esto:

<TextView
        android:id="@+id/textViewHello2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World 2"
        style="@style/OswaldTextAppearance"/>

<style name="OswaldTextAppearance">
        <item name="android:tag">fonts/Oswald-Regular.ttf</item>
        <item name="android:textColor">#000000</item>
</style>

Ahora puede acceder / configurar explícitamente la vista como:

TextView textView = TextViewHelper.setupTextView(this, R.id.textViewHello1).setText("blah");

o simplemente configurar todo a través de:

TextViewHelper.setupTextViews(this, (ViewGroup) findViewById(R.id.parentLayout)); // parentLayout is the root view group (relative layout in my case)

¿Y cuál es la clase de magia que preguntas? Principalmente pegado de otras publicaciones SO, con métodos auxiliares para la actividad y los fragmentos:

import android.app.Activity;
import android.content.Context;
import android.graphics.Typeface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.HashMap;
import java.util.Map;

public class TextViewHelper {
    private static final Map<String, Typeface> mFontCache = new HashMap<>();

    private static Typeface getTypeface(Context context, String fontPath) {
        Typeface typeface;
        if (mFontCache.containsKey(fontPath)) {
            typeface = mFontCache.get(fontPath);
        } else {
            typeface = Typeface.createFromAsset(context.getAssets(), fontPath);
            mFontCache.put(fontPath, typeface);
        }
        return typeface;
    }

    public static void setupTextViews(Context context, ViewGroup parent) {
        for (int i = parent.getChildCount() - 1; i >= 0; i--) {
            final View child = parent.getChildAt(i);
            if (child instanceof ViewGroup) {
                setupTextViews(context, (ViewGroup) child);
            } else {
                if (child != null) {
                    TextViewHelper.setupTextView(context, child);
                }
            }
        }
    }

    public static void setupTextView(Context context, View view) {
        if (view instanceof TextView) {
            if (view.getTag() != null) // also inherited from TextView's style
            {
                TextView textView = (TextView) view;
                String fontPath = (String) textView.getTag();
                Typeface typeface = getTypeface(context, fontPath);
                if (typeface != null) {
                    textView.setTypeface(typeface);
                }
            }
        }
    }

    public static TextView setupTextView(View rootView, int id) {
        TextView textView = (TextView) rootView.findViewById(id);
        setupTextView(rootView.getContext().getApplicationContext(), textView);
        return textView;
    }

    public static TextView setupTextView(Activity activity, int id) {
        TextView textView = (TextView) activity.findViewById(id);
        setupTextView(activity.getApplicationContext(), textView);
        return textView;
    }
}

4

Lamentablemente no hay una buena solución para esto.

He visto muchos artículos sobre el uso de una vista de texto personalizada, pero lo olvidan porque no solo las vistas de texto pueden implementar fuentes y hay vistas de texto ocultas en otras vistas inaccesibles para el desarrollador; Ni siquiera voy a comenzar con Spannable .

Puede usar una utilidad de fuente externa como:

Herramienta de fuente de caligrafía

PERO Esto recorre cada vista de la aplicación en su creación e incluso esta utilidad pierde algunas vistas (ViewPager representa la fuente normal), entonces tiene el problema de que cuando Google actualiza sus herramientas de compilación, esto ocasionalmente se bloqueará porque necesita apuntar a propiedades obsoletas. También es un poco lento, ya que utiliza la reflexión de Java .

Depende de Google arreglar esto. Necesitamos un mejor soporte de fuentes en Android. Si nos fijamos en la solución de iOS, literalmente tienen cientos de fuentes incorporadas para elegir. ¿Quieres una fuente personalizada? Simplemente coloque un TFF y podrá usarlo.

Por ahora, ahora estamos limitados a la oferta que nos ofrece Google, que es extremadamente limitada pero afortunadamente optimizada para dispositivos móviles.


2

Asegúrese de pegar el código anterior en onCreate () después de su llamada al super y la llamada a setContentView (). Este pequeño detalle me mantuvo colgado por un tiempo.


2

Con Android 8.0, el uso de fuentes personalizadas en la aplicación se hizo fácil con downloadable fonts. Podemos agregar fuentes directamente a la res/font/ foldercarpeta del proyecto, y al hacerlo, las fuentes estarán automáticamente disponibles en Android Studio.

Carpeta en resolución con nombre de fuente y tipo establecido en Fuente

Ahora configure el fontFamilyatributo en la lista de fuentes o haga clic en más y seleccione la fuente de su elección. Esto agregará tools:fontFamily="@font/your_font_file"línea a su TextView.

Esto generará automáticamente pocos archivos.

1. En la carpeta de valores se creará fonts_certs.xml.

2. En Manifiesto agregará estas líneas:

  <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" /> 

3) preloaded_fonts.xml

<resources>
    <array name="preloaded_fonts" translatable="false">
        <item>@font/open_sans_regular</item>
        <item>@font/open_sans_semibold</item>
    </array>
</resources>

2

Puede usar la biblioteca de terceros EasyFonts fácil y simple para configurar una variedad de fuentes personalizadas para su TextView. Al usar esta biblioteca, no debería tener que preocuparse por descargar y agregar fuentes a la carpeta de recursos / fuentes. También sobre la creación de objetos tipográficos.

En vez de

Typeface myTypeface = Typeface.createFromAsset(getAssets(), "fonts/myFont.ttf");
TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(myTypeface);

Simplemente:

TextView myTextView = (TextView)findViewById(R.id.myTextView);
myTextView.setTypeface(EasyFonts.robotoThin(this));

Esta biblioteca también proporciona la siguiente fuente.

  • Roboto
  • Droid Serif
  • Robot droide
  • Libertad
  • Fun Raiser
  • Nación Android
  • Aguacate verde
  • Reconocimiento

1

Tuve el mismo problema, el TTF no apareció. Cambié el archivo de fuente, y con el mismo código está funcionando.


1

Si desea cargar la fuente desde la red o diseñarla fácilmente, puede usar:

https://github.com/shellum/fontView

Ejemplo:

<!--Layout-->
<com.finalhack.fontview.FontView
        android:id="@+id/someFontIcon"
        android:layout_width="80dp"
        android:layout_height="80dp" />

//Java:
fontView.setupFont("http://blah.com/myfont.ttf", true, character, FontView.ImageType.CIRCLE);
fontView.addForegroundColor(Color.RED);
fontView.addBackgroundColor(Color.WHITE);

1

Bueno, después de siete años, puedes cambiar la aplicación completa textViewo lo que quieras fácilmente usando las android.supportbibliotecas 26 ++.

P.ej:

Cree su paquete de fuentes app / src / res / font y mueva su fuente a él.

ingrese la descripción de la imagen aquí

Y en el tema de su aplicación simplemente agréguelo como fuente Familia:

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

Ejemplo de uso textViewsolo con :

<style name="fontTextView" parent="@android:style/Widget.TextView">
    <item name="android:fontFamily">monospace</item>
</style>

Y agregue a su tema principal:

<item name="android:textViewStyle">@style/fontTextView</item>

Actualmente se ha trabajado en 8.1 hasta 4.1 API Jelly Bean y eso es una amplia gama.


1

Respuesta de actualización: Android 8.0 (API nivel 26) presenta una nueva característica, Fuentes en XML. solo use la función Fuentes en XML en dispositivos con Android 4.1 (API nivel 16) y superior, use la Biblioteca de soporte 26.

ver este enlace


Vieja respuesta

Hay dos formas de personalizar las fuentes:

!!! mi fuente personalizada en assets / fonts / iran_sans.ttf



Camino 1: Refrection Typeface.class ||| mejor manera

llamar a FontsOverride.setDefaultFont () en la clase extiende la aplicación, este código hará que se cambien todas las fuentes de software, incluso las fuentes Toast

AppController.java

public class AppController extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        //Initial Font
        FontsOverride.setDefaultFont(getApplicationContext(), "MONOSPACE", "fonts/iran_sans.ttf");

    }
}

FontsOverride.java

public class FontsOverride {

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

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



Camino 2: use setTypeface

para una vista especial solo llame a setTypeface () para cambiar la fuente.

CTextView.java

public class CTextView extends TextView {

    public CTextView(Context context) {
        super(context);
        init(context,null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        // use setTypeface for change font this view
        setTypeface(FontUtils.getTypeface("fonts/iran_sans.ttf"));

    }
}

FontUtils.java

public class FontUtils {

    private static Hashtable<String, Typeface> fontCache = new Hashtable<>();

    public static Typeface getTypeface(String fontName) {
        Typeface tf = fontCache.get(fontName);
        if (tf == null) {
            try {
                tf = Typeface.createFromAsset(AppController.getInstance().getApplicationContext().getAssets(), fontName);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            fontCache.put(fontName, tf);
        }
        return tf;
    }

}



0
  • Abra su proyecto y seleccione Proyecto en la parte superior izquierda
  • aplicación -> src -> principal
  • haga clic derecho en principal y cree el nombre del directorio como activos
  • clic derecho para assest y crear nuevo nombre de directorio en el que las fuentes
  • necesita encontrar fuentes gratuitas como fuentes gratuitas
  • dáselo a tu vista de texto y llámalo en tu clase de actividad
  • copia tus fuentes dentro de la carpeta de fuentes
  • TextView txt = (TextView) findViewById(R.id.txt_act_spalsh_welcome); Typeface font = Typeface.createFromAsset(getAssets(), "fonts/Aramis Italic.ttf"); txt.setTypeface(font);

el nombre de la fuente debe ser correcto y divertirse


0

Sí, las fuentes descargables son muy fáciles, como dijo Dipali .

Así es como lo haces ...

  1. Lugar a TextView.
  2. En el panel de propiedades, seleccione el fontFamilymenú desplegable. Si no está allí, encuentre el elemento de intercalación (el> y haga clic en él para expandirlo textAppearance) debajo de.
  3. Expande el font-familymenú desplegable.
  4. En la pequeña lista, desplácese hacia abajo hasta que vea more fonts
  5. Esto abrirá un cuadro de diálogo desde el que puede buscar Google Fonts
  6. Busque la fuente que le gusta con la barra de búsqueda en la parte superior
  7. Selecciona tu fuente.
  8. Seleccione el estilo de la fuente que desee (es decir, negrita, normal, cursiva, etc.)
  9. En el panel derecho, elija el botón de radio que dice Add font to project
  10. Haz clic en Aceptar ¡Ahora su TextView tiene la fuente que le gusta!

BONIFICACIÓN: si desea diseñar TODO con texto en su aplicación con la fuente elegida, simplemente agregue <item name="android:fontfamily">@font/fontnamehere</item>a sustyles.xml


deberías haber apreciado mi respuesta que! :)
Dipali s.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.