studio - Android: ¿Cómo declarar de forma personalizada el espacio de nombres XML en styles.xml?
styles.xml android (8)
1) necesita definir un atributo para sus fuentes en el archivo attr.xml en la carpeta res:
<attr name="myfonts" format="string"></attr>
2) necesita definir un estilo personalizado para su TextView y aquí usamos nuestro atributo definido (myfonts):
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
3)
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
Resumen de lo que tienes hasta ahora:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myfonts" format="string">
</attr>
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
</resources>
4) Ahora su diseño sería:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.MyCustomTextView
android:id="@+id/result"
style="@style/CoolTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="HELLO WORLD!"
android:textSize="24dp"
android:gravity="center" >
</com.example.MyCustomTextView>
</RelativeLayout>
5) y su MyCustomTextView es:
public class MyCustomTextView extends TextView {
private static final String TAG = "TextView";
public MyCustomTextView(Context context) {
super(context);
}
public MyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
settingFont(context, attrs);
}
public MyCustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
settingFont(context, attrs);
}
private void settingFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.MyCustomStyle);
String customFont = a.getString(R.styleable.MyCustomStyle_myfonts);
Typeface tf = null;
try {
tf = Typeface.createFromAsset(ctx.getAssets(), customFont);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
a.recycle();
return;
}
setTypeface(tf);
a.recycle();
}
}
Asumí que pusiste la fuente en el directorio de activos / fuentes no .
También recomiendo encarecidamente leer this .
Estoy tratando de poner el espacio de nombres XML personalizado en styles.xml
y heredarlo en el diseño. No sé cómo declarar el espacio de nombres XML personalizado en el styles.xml
como lo hago en el diseño xml (por ejemplo, xmlns:app="http://schemas.android.com/tools"
).
¿Cómo uso el espacio de nombres XML personalizado en el styles.xml
?
Lo que tengo:
El recurso de fuente,
ReallyCoolFont.ttf
se guarda en elasset/fonts
.my_layout.xml
:<TextView <!-- more attributes here --> app:customFont="fonts/ReallyCoolFont.ttf" <!-- more attributes here --> </TextView>
styles.xml
:<style name="CoolTextView"> <!-- more items here --> <!-- more items here --> </style>
Lo que me gustaría tener:
my_layout.xml
:<TextView <!-- more attributes here --> style="@style/CoolTextView <!-- more attributes here --> </TextView>
styles.xml
:<style name="CoolTextView"> <!-- more items here --> <item name="app:customFont">ReallyCoolFont.ttf</item> <!-- more items here --> </style>
Error me sale:
Error:(1403, 21) No resource found that matches the given name: attr ''app:customFont''.
He hecho el siguiente para una fuente personalizada CustomTextView
public class KlavikaTextView extends TextView {
private final static int KLAVIKA_BOLD = 0;
private final static int KLAVIKA_BOLD_ITALIC = 1;
private final static int KLAVIKA_LIGHT = 2;
private final static int KLAVIKA_LIGHT_ITALIC = 3;
private final static int KLAVIKA_MEDIUM = 4;
private final static int KLAVIKA_MEDIUM_ITALIC = 5;
private final static int KLAVIKA_REGULAR = 6;
private final static int KLAVIKA_REGULAR_ITALIC = 7;
public KlavikaTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
public KlavikaTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
public KlavikaTextView(Context context) {
super(context);
}
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.KlavikaTextView);
// The value 0 is a default, but shouldn''t ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.KlavikaTextView_typeface, KLAVIKA_REGULAR);
// You can instantiate your typeface anywhere, I would suggest as a
// singleton somewhere to avoid unnecessary copies
switch (typeface) {
case KLAVIKA_BOLD:
setTypeface(App.klavikaBold);
break;
case KLAVIKA_BOLD_ITALIC:
setTypeface(App.klavikaBoldItalic);
break;
case KLAVIKA_LIGHT:
setTypeface(App.klavikaLight);
break;
case KLAVIKA_LIGHT_ITALIC:
setTypeface(App.klavikaLightItalic);
break;
case KLAVIKA_MEDIUM:
setTypeface(App.klavikaMedium);
break;
case KLAVIKA_MEDIUM_ITALIC:
setTypeface(App.klavikaMediumItalic);
break;
case KLAVIKA_REGULAR_ITALIC:
setTypeface(App.klavikaRegularItalic);
break;
case KLAVIKA_REGULAR:
default:
setTypeface(App.klavikaRegular);
break;
}
}}
Luego en los valores que he creado attr.xml
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="klavika_bold" value="0" />
<enum name="klavika_bold_italic" value="1" />
<enum name="klavika_light" value="2" />
<enum name="klavika_light_italic" value="3" />
<enum name="klavika_medium" value="4" />
<enum name="klavika_medium_italic" value="5" />
<enum name="klavika_regular" value="6" />
<enum name="klavika_regular_italic" value="7" />
</attr>
<!--
Tell Android that the class "KlavikaTextView" can be styled,
and which attributes it supports-->
<declare-styleable name="KlavikaTextView">
<attr name="typeface" />
</declare-styleable>
A continuación creó el estilo.
<style name="TextView.Example">
<item name="typeface">klavika_bold</item>
</style>
Este estilo que puedes usar para tus diseños xml
style="@style/TextView.Example"
La respuesta es NO especificar el espacio de nombres en el estilo.
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:custom="http://schemas.android.com/apk/res/com.custom.project">
<style name="CustomStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="customAttr">value</item> <!-- tee hee -->
</style>
</resources>
Los atributos personalizados se definen utilizando etiquetas <declare-styleable>
; Normalmente el archivo se llama attrs.xml. La declaración de espacio de nombres tendrá el nombre del paquete de su aplicación.
El proceso completo se describe aquí: Creación de una clase de vista | Desarrolladores de Android
No es necesario agregar ningún prefijo para hacer referencia a sus atributos personalizados en los archivos de recursos de estilo. Hacerlo así funcionará bien:
<style name="CoolTextView">
<item name="customFont">ReallyCoolFont.ttf</item>
</style>
No necesitas ningún prefijo, funcionará sin ellos. Este es el código de uno de mis proyectos, que funciona bien
<style name="defaultTriangle">
<item name="triangleColor">#FF33B5E5</item>
<item name="triangleStrokeColor">@android:color/black</item>
<item name="triangleStrokeWidth">3dp</item>
</style>
<si.kseneman.views.Triangle
style="@style/defaultTriangle"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:padding="10dp"
android:rotation="0"
/>
¡Solución rápida vía código!
String pathFont = "fonts/ReallyCoolFont.ttf";
TextView text = (TextView) findViewById(R.id.TextView1);
Typeface fontFace = Typeface.createFromAsset( getAssets(), pathFont );
text.setTypeface( fontFace );
Bibliotecas de terceros , resuelve el problema, en XML!
1 - https://github.com/leok7v/android-textview-custom-fonts
2 - https://github.com/ragunathjawahar/android-typeface-textview
Mi sugerencia
Tendrá otras necesidades, y para cada componente tendrá que personalizar una clase.
Otro problema es que tiene otros diseños y componentes N TextView para el mantenimiento , tendrá mucho trabajo.
Utilizo este método en proyectos en el OnCreate de mi actividad si necesito cambiar la fuente. Tengo que hacer esto solo en el método OnCreate de cada actividad.
private static final String FONT = "ReallyCoolFont.ttf";
public static void allTextView(final Context context, final View root) {
String fontPath = FONT;
try {
if (root instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) root;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++)
allTextView(context, viewGroup.getChildAt(i) );
} else if (root instanceof TextView)
((TextView) root).setTypeface(Typeface.createFromAsset(context.getAssets(), fontPath));
} catch (Exception e) {
e.printStackTrace();
}
}
// call in OnCreate Activity
allTextView(this, findViewById(R.layout.main) );
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.my.project">
<style name="my_style"> <item name="custom:tag">some_value</item> </style>
</resources>
está intentando aplicar el espacio de nombres XML a un valor de atributo, que no funcionará. En este caso, debe especificar el nombre del paquete directamente, de esta manera:
<style name="my_style"> <item name="com.my.project:tag">some_value</item> </style>