studio - como agregar fuentes a android
Cómo configurar la familia de fuentes predeterminada para toda la aplicación de Android (12)
Estoy usando la fuente de luz Roboto en mi aplicación. Para configurar la fuente, tengo que agregar el android:fontFamily="sans-serif-light"
a cada vista. ¿Hay alguna forma de declarar la fuente Roboto como familia de fuentes predeterminada para toda la aplicación? Lo he intentado así, pero no parece funcionar.
<style name="AppBaseTheme" parent="android:Theme.Light"></style>
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:fontFamily">sans-serif-light</item>
</style>
Android no proporciona mucho soporte para la aplicación de fuentes en toda la aplicación (consulte este issue ). Tienes 4 opciones para establecer la fuente para toda la aplicación:
- Opción 1: aplicar reflexión para cambiar la fuente del sistema
- Opción 2: crear y subclase clases de vista personalizadas para cada vista que necesita una fuente personalizada
- Opción 3: implementar un rastreador de vistas que atraviese la jerarquía de vistas para la pantalla actual
- Opción 4: utilizar una biblioteca de terceros.
Los detalles de estas opciones se pueden encontrar here .
Con el lanzamiento de Android Oreo, puede utilizar la biblioteca de soporte para alcanzar este objetivo.
- Verifique su aplicación build.gradle si tiene la biblioteca de soporte > = 26.0.0
- Agregue la carpeta " fuente " a su carpeta de recursos y agregue allí sus fuentes
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>
Consulte developer.android.com/guide/topics/ui/look-and-feel/… para obtener información más detallada.
La respuesta es no, no puedes. Consulte ¿Es posible establecer una fuente personalizada para toda la aplicación? para más información.
Hay soluciones, pero nada en la línea de "una sola línea de código aquí y todas mis fuentes será esto en lugar de eso ".
(Agradezco a Google, y a Apple, por eso). Las fuentes personalizadas tienen un lugar, pero hacerlas fáciles de reemplazar en toda la aplicación, habría creado todo un mundo de aplicaciones Comic Sans )
La respuesta es sí.
Luz global de Roboto 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 desea de la lista themes.xml , luego cree su estilo personalizado basado en el original. Al final, aplica el estilo como el tema de la aplicación.
<application
android:theme="@style/AppTheme" >
</application>
Funcionará solo con fuentes incorporadas como Roboto, pero esa era la pregunta. Para fuentes personalizadas (cargadas de activos, por ejemplo) este método no funcionará.
EDITAR 13/08/15
Si está utilizando temas de AppCompat, recuerde eliminar android:
prefix. 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 buttonStyle
no contiene el prefijo de android:
, pero textViewStyle
debe contenerlo.
No hable de rendimiento, para una 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 un TextView:
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 su actividad, pase el ViewGroup actual después de setContentView y listo:
ViewGroup group = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content);
Font.setAllTextView(group);
Por fragmento puedes hacer algo similar.
Otra forma de hacer esto para toda la aplicación es usar la 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, cuando quiera anular las fuentes, puede simplemente llamar al método y asignarle un mapa de los 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 check ejemplo completo
Esto solo funciona para Android SDK 21 y superior para versiones anteriores. Verifique el ejemplo completo.
Podrías usar Caligrafía para gestionar fuentes con Android
Prueba esta biblioteca, es liviana 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" />
Sé que esta pregunta es bastante antigua, pero he encontrado una buena solución. Básicamente, usted pasa un diseño de contenedor a esta función, y aplicará la fuente a todas las vistas compatibles, y recursivamente cicle 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) { }
}
}
Solo usa este lib compílalo en tu archivo de calificaciones
complie''me.anwarshahriar:calligrapher:1.0''
y usarlo 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 rápida de hacer eso.
LEER ACTUALIZACIONES ABAJO
Tuve el mismo problema con la incrustación de una nueva fuente y finalmente conseguí que funcionara con la extensión de TextView y la fuente dentro del mismo.
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 de TextView más adelante de a en cada elemento. Y si usas el creador de interfaz de usuario en Eclipse, a veces no muestra correctamente las vistas de texto. Fue lo único que me funcionó ...
ACTUALIZAR
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 esta publicación SO
ACTUALIZACIÓN 2
Comenzando con el nivel 26 de API y disponible en la ''biblioteca de soporte'' que puede usar
android:fontFamily="@font/embeddedfont"
Más información: Fuentes en XML.
para simplemente establecer el tipo de letra de la aplicación en normal
, sans
, serif
o monospace
(no en una fuente personalizada), puede hacer esto.
define un tema y configura el atributo android:typeface
al tipo de letra que quieres 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>
aplique 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>