letra - ¿Cómo configurar una fuente personalizada para una aplicación completa en Android?
fuentes para android (12)
¿Es posible establecer una fuente personalizada en una aplicación de Android?
Intenté lo que se publica
here
, pero no sé dónde está mi clase de
extends Application
...
¿Alguna ayuda?
EDITAR:
Intenté lo siguiente:
- Agregue una carpeta de activos e inserte la fuente dentro como se ve aquí:
-
Agregue una nueva clase que se extienda desde la
Application
-
Llame a esta nueva clase desde mi
AndroidManifest.xml
. -
Fui a mi estilo y lo agregué.
MyApp.java:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
FontsOverride.setDefaultFont(this, "DEFAULT", "raleway_regular.ttf");
// This FontsOverride comes from the example I posted above
}
}
AndroidManifest.xml:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".MyApp"
android:theme="@style/AppTheme">
....
styles.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:fontFamily">default</item>
</style>
Pero mi fuente todavía no está cambiando ... ¿alguna idea?
Entonces se llama a la clase
MyApp
.
Pero ningún efecto en mis fuentes ...
EDIT2: Me di cuenta de que mis botones aplican la fuente personalizada después de configurar un estilo personalizado para mis botones. Aquí está mi estilo de botón personalizado:
<style name="MyButtonStyle" parent="Widget.AppCompat.Button">
<item name="textAllCaps">false</item>
<item name="android:textAllCaps">false</item>
</style>
Y así es como se ve ahora:
Entonces: mi botón está aplicando el estilo, pero no
TextView
.
¿Alguna idea de por qué mi fuente personalizada no se aplica a todos los elementos de la aplicación?
Android proporciona soluciones más simples y mejores que son compatibles con el nivel 14 de API por Support Library 26+. Fuentes en XML También admite la opción de familia de fuentes .
Siga estos sencillos pasos y la familia de fuentes se aplicará en su aplicación sin ningún obstáculo:
- Crear un directorio de fuentes dentro de res
- Pegue su archivo de fuentes dentro de la fuente
- Haga clic derecho en la carpeta de fuentes y vaya a Nuevo> Archivo de recursos de fuentes. Aparece la ventana Nuevo archivo de recursos.
- Agregar los siguientes atributos
<?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/lobster_regular" /> <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/lobster_italic" /> </font-family>
- En el archivo xml anterior. Use la aplicación solo para usar la biblioteca de soporte. De lo contrario, puede usar Android si su aplicación se dirige al nivel API 26+.
-
Ahora ve a tu styles.xml y coloca debajo de la línea en tu estilo principal.
<item name="android:fontFamily">@font/opensans</item>
- Importante: Use AppCompatActivity solo si está usando la biblioteca de soporte.
-
O use a continuación para configurar el tipo de letra mediante programación
view.setTypeface(ResourcesCompat.getFont(context, R.font.opensans));
Cree la carpeta de activos en la carpeta principal fonts.add fonts. agregue su archivo .ttf en la carpeta de fuentes.
Agregue lo siguiente en el tema de su aplicación:
<item name="android:fontFamily">@font/roboto_regular</item>
<item name="fontFamily">@font/roboto_regular</item>
Crear clase como TypefaceUtil
import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;
import java.lang.reflect.Field;
public class TypefaceUtil {
/**
* Using reflection to override default typeface
* NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
* @param context to work with assets
* @param defaultFontNameToOverride for example "monospace"
* @param customFontFileNameInAssets file name of the font from assets
*/
public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
try {
final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);
final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
defaultFontTypefaceField.setAccessible(true);
defaultFontTypefaceField.set(null, customFontTypeface);
} catch (Exception e) {
Log.e("Can not set","Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
}
}
}
Llámalo en la clase de aplicación o en la actividad del iniciador
TypefaceUtil.overrideFont(getApplicationContext(), "fonts/roboto_regular.ttf", "fonts/roboto_regular.ttf"); // font from assets: "assets/fonts/Roboto-Regular.ttf
Escribir una clase
public class MyApp extends Application{
// Put the onCreate code as you obtained from the post link you reffered
}
ahora lo siguiente está en AndroidManifest.xml para la etiqueta de la aplicación que da nombre a la clase de la aplicación. En este caso es MyApp
<application
android:name=".MyApp"
...
>
...
</application>
Entonces, cada vez que se abra la aplicación, se invocará el método onCreate de la clase MyApp y se establecerá la fuente.
Actualizar Poner archivo de fuente en assets / fonts / your_font_file.ttf
Coloque esta línea en el método onCreate de su clase de aplicación (MyApp)
TypefaceUtil.overrideFont(getApplicationContext(), "SERIF", "fonts/your_font_file.ttf");
Archivo de origen para TypefaceUtil
public class TypefaceUtil {
/**
* Using reflection to override default typeface
* NOTICE: DO NOT FORGET TO SET TYPEFACE FOR APP THEME AS DEFAULT TYPEFACE WHICH WILL BE OVERRIDDEN
*
* @param context to work with assets
* @param defaultFontNameToOverride for example "monospace"
* @param customFontFileNameInAssets file name of the font from assets
*/
public static void overrideFont(Context context, String defaultFontNameToOverride, String customFontFileNameInAssets) {
final Typeface customFontTypeface = Typeface.createFromAsset(context.getAssets(), customFontFileNameInAssets);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Map<String, Typeface> newMap = new HashMap<String, Typeface>();
newMap.put("serif", customFontTypeface);
try {
final Field staticField = Typeface.class
.getDeclaredField("sSystemFontMap");
staticField.setAccessible(true);
staticField.set(null, newMap);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
try {
final Field defaultFontTypefaceField = Typeface.class.getDeclaredField(defaultFontNameToOverride);
defaultFontTypefaceField.setAccessible(true);
defaultFontTypefaceField.set(null, customFontTypeface);
} catch (Exception e) {
Log.e(TypefaceUtil.class.getSimpleName(), "Can not set custom font " + customFontFileNameInAssets + " instead of " + defaultFontNameToOverride);
}
}
}
}
Ahora actualice su archivo style.xml
ponga la línea de abajo su estilo que se incluye para su actividad en el archivo de manifiesto
<item name="android:typeface">serif</item>
Espero que esto ayude
Hay una gran biblioteca para fuentes personalizadas en Android: caligrafía
Aquí hay una muestra de cómo usarlo.
En Gradle necesita poner esta línea en el archivo build.gradle de su aplicación:
dependencies {
compile ''uk.co.chrisjenx:calligraphy:2.2.0''
}
Y luego crea una clase que extienda la aplicación y escribe este código:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("your font path")
.setFontAttrId(R.attr.fontPath)
.build()
);
}
}
Debería haber hecho en los activos / un "Nuevo directorio" "fuentes" (ver más abajo), por lo que en ese código "su ruta de fuente" debe ser "fuentes / SourceSansPro-Regular.ttf". (Es solo "fuentes ..." no "/ fuentes .." o "activos ...")
Y en la clase de actividad ponga este método antes de onCreate:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
Y lo último que debería tener su archivo de manifiesto debería ser así:
<application
.
.
.
android:name=".App">
¡Y cambiará toda la actividad a tu fuente! ¡Es simple y limpio!
En Activos, debe hacer clic con el botón derecho en Nuevo directorio, llamarlo "fuentes".
En el buscador coloca los archivos de fuente
.ttf
allí.
Además, no olvidó agregar debajo de dos líneas en attrs.xml, si no tiene el archivo attrs.xml, cree un nuevo archivo en values.xml
<attr format="string" name="fontPath"/>
<item name="calligraphy_tag_id" type="id"/>
Parece que está usando
android:fontFamily
lugar de
android:typeface
en su
styles.xml
.
Intenta reemplazar
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:fontFamily">default</item>
</style>
con
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:typeface">default</item>
</style>
Primero, cree una nueva clase que anule cualquier vista que desee personalizar.
(por ejemplo, ¿quiere un botón con un tipo de letra personalizado?
Button
Extender).
Por ejemplo:
public class CustomButton extends Button {
private final static int ROBOTO = 0;
private final static int ROBOTO_CONDENSED = 1;
public CustomButton(Context context) {
super(context);
}
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs); //I''ll explain this method later
}
public CustomButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
}
Ahora, si no tiene uno, agregue un documento XML en
res/values/attrs.xml
y agregue:
<resources>
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="roboto" value="0"/>
<enum name="robotoCondensed" value="1"/>
</attr>
<!-- Tell Android that the class "CustomButton" can be styled,
and which attributes it supports -->
<declare-styleable name="CustomButton">
<attr name="typeface"/>
</declare-styleable>
</resources>
Bien, con eso fuera del camino, volvamos al método
parseAttributes()
de antes:
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomButton);
//The value 0 is a default, but shouldn''t ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.CustomButton_typeface, 0);
switch(typeface) {
case ROBOTO: default:
//You can instantiate your typeface anywhere, I would suggest as a
//singleton somewhere to avoid unnecessary copies
setTypeface(roboto);
break;
case ROBOTO_CONDENSED:
setTypeface(robotoCondensed);
break;
}
values.recycle();
}
Ahora estás listo. Puede agregar más atributos para cualquier cosa (podría agregar otro para typefaceStyle: negrita, cursiva, etc.) pero ahora veamos cómo usarlo:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.yourpackage.name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.yourpackage.name.CustomButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me!"
custom:typeface="roboto" />
</LinearLayout>
La línea
xmlns:custom
realmente puede ser cualquier cosa, pero la convención es lo que se muestra arriba.
Lo que importa es que es único, y por eso se usa el nombre del paquete.
Ahora solo usa el prefijo
custom:
para sus atributos, y el prefijo
android:
para atributos de Android.
Una última cosa: si desea usar esto en un estilo (
res/values/styles.xml
), no debe agregar la línea
xmlns:custom
.
Simplemente haga referencia al nombre del atributo sin prefijo:
<style name="MyStyle>
<item name="typeface">roboto</item>
</style>
Prueba el siguiente código, funciona para mí, espero que también te ayude.
public class BaseActivity extends AppCompatActivity {
private Typeface typeace;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
typeace = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name));
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
overrideFonts(this,getWindow().getDecorView());
}
private 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(typeace);
} else if (v instanceof EditText ) {
((EditText) v).setTypeface(typeace);
} else if (v instanceof Button) {
((Button) v).setTypeface(typeace);
}
} catch (Exception e) {
}
}
}
Ahora extienda esta BaseActivity a cualquiera de su Actividad o puede crear la misma clase para el fragmento si está utilizando.
Nota: - Si desea establecer algunos tipos de letra de vista diferentes, entonces debe configurarlos mediante programación como se muestra a continuación
private Typeface typeface;
typeface = Typeface.createFromAsset(getAssets(), getResources().getString(R.string.font_name_bold));
tvUserName.setTypeface(typeface);
Así que pruébalo y avísame, si pudiera ayudarte más
Puede hacerlo con el SDK de Android ahora, como el canal oficial de YouTube para desarrolladores de Android publicado en set / 2017 here .
Requiere API Nivel 26 (Android 8 Oreo) y superior.
Solo necesita colocar su archivo de fuente en la carpeta
res/font
y hacer referencia a ellos en su
TextView
en caso de que necesite uno específico con el atributo
android:fontFamily
.
Si desea una fuente base en toda su aplicación, simplemente ponga
<item name="android:fontFamily">@font/yourfontname</item>
en tu
styles.xml
Puede descargar una fuente personalizada de Android Studio y sobre la marcha si lo desea también. Todo esto lo puedes encontrar con detalles en el video de arriba.
Si sigue el primer tema, esto debería funcionar: Here
Si con reflexion. Esto funciona ( basado en esta respuesta ):
(Nota: esta es una solución alternativa debido a la falta de soporte para las fuentes personalizadas, por lo que si desea cambiar esta situación, por favor marque el tema de Android aquí). Nota: No deje comentarios "yo también" sobre ese tema, todos los que lo han visto reciben un correo electrónico cuando lo hace. Así que solo "estrella" por favor.
import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected 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();
}
}
}
Luego debe sobrecargar las pocas fuentes predeterminadas, por ejemplo en una clase de aplicación:
public final class Application extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
FontsOverride.setDefaultFont(this, "DEFAULT", "MyFontAsset.ttf");
FontsOverride.setDefaultFont(this, "MONOSPACE", "MyFontAsset2.ttf");
FontsOverride.setDefaultFont(this, "SERIF", "MyFontAsset3.ttf");
FontsOverride.setDefaultFont(this, "SANS_SERIF", "MyFontAsset4.ttf");
}
}
O, por supuesto, si está utilizando el mismo archivo de fuente, puede mejorarlo para cargarlo solo una vez.
Sin embargo, tiendo a anular uno, decir "MONOSPACE", luego configurar un estilo para forzar la aplicación de tipo de letra en toda la extensión:
<resources>
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:typeface">monospace</item>
</style>
</resources>
API 21 Android 5.0
He investigado los informes en los comentarios de que no funciona y parece ser incompatible con el tema android: Theme.Material.Light.
Si ese tema no es importante para usted, use un tema anterior, por ejemplo:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:typeface">monospace</item>
</style>
También probé la anulación de fuentes, pero al final no es una solución confiable, lamentablemente anular las fuentes toma más que eso. Puede esperar a que salga Android O con una fuente personalizada o usar una biblioteca de terceros.
La última solución con la que me encontré fue esta biblioteca Caligraphy , que fue fácil de iniciar y le permitió usar tantas fuentes como quisiera. Mientras revisaba su código fuente, entendí por qué anular las fuentes no funcionaría, así que incluso si no planea usarlo, le recomiendo leerlo una vez ...
Buena suerte
Todo lo que hice fue:
1: Se agregó "nuevo directorio de recursos" a la carpeta RES, se seleccionó TIPO DE RECURSO como "fuente" del menú desplegable dado, se nombró el nuevo directorio "fuente" y se guardó.
2: Agregué mi "custom_font.ttf" a la carpeta FONT que acaba de crear.
3: Agregué mi fuente personalizada en el tema base de la aplicación en STYLES.XML
HECHO.
Una solución para Kotlin será esto
Gist de la solución https://gist.github.com/Johnyoat/040ca5224071d01b3f3dfc6cd4d026f7
Paso uno
Coloque el archivo de fuente en assets / fonts / your_font_file.ttf y cree una clase kotlin llamada TypeFaceUtil
class TypefaceUtil{
fun overridefonts(context: Context, defaultFontToOverride:String, customFontFileNameInAssets:String){
try {
val customTypeface = Typeface.createFromAsset(context.assets,customFontFileNameInAssets)
val defaultTypefaceField = Typeface::class.java.getDeclaredField(defaultFontToOverride)
defaultTypefaceField.isAccessible = true
defaultTypefaceField.set(null,customTypeface)
}catch (e:Exception){
Timber.e("Cannot set font $customFontFileNameInAssets instead of $defaultFontToOverride")
}
}
}
Paso dos
Luego en tu
onCreate
val typefaceUtil = TypefaceUtil()
typefaceUtil.overridefonts(this,"SERIF","fonts/font_file.ttf")
Paso tres
agrega esto a tu estilo
<item name="android:typeface">serif</item>