Android: Как настраивать-объявить пространство имен XML в styles.xml?
Я пытаюсь помещать собственное пространство имен XML в styles.xml
и наследовать его в макете. Я не знаю, как объявить пользовательское пространство имен XML в styles.xml
, как это делается в макете xml (например, xmlns:app="http://schemas.android.com/tools"
).
Как использовать собственное пространство имен XML в styles.xml
?
Что у меня:
-
Атрибут font, ReallyCoolFont.ttf
сохраняется в asset/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>
Что бы я хотел:
-
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:(1403, 21) No resource found that matches the given name: attr 'app:customFont'.
Ответы
Ответ 1
1) вам нужно определить атрибут для ваших шрифтов в файле attr.xml в папке res:
<attr name="myfonts" format="string"></attr>
2) вам нужно определить собственный стиль для вашего TextView, и здесь мы используем наш определенный атрибут (myfonts):
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
3)
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
сводка о том, что у вас есть до сих пор:
<?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) Теперь ваш макет будет выглядеть следующим образом:
<?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), а ваш MyCustomTextView:
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();
}
}
Я предположил, что вы помещаете шрифт в ресурс не в каталог ресурс/шрифты.
также я настоятельно рекомендую прочитать этот.
Ответ 2
Вам не нужно добавлять префикс для ссылки на ваши пользовательские атрибуты в файлах ресурсов стиля. Выполнение этого так будет работать отлично:
<style name="CoolTextView">
<item name="customFont">ReallyCoolFont.ttf</item>
</style>
Ответ 3
Вам не нужны префиксы, они будут работать без них. Это код из одного из моих проектов, который работает просто отлично
<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"
/>
Ответ 4
Ответ: НЕ указывать пространство имен в стиле.
<?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>
Ответ 5
Я сделал следующий для пользовательского шрифта
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;
}
}}
Затем в значениях, которые я создал, 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>
Далее создан стиль
<style name="TextView.Example">
<item name="typeface">klavika_bold</item>
</style>
Этот стиль, который вы можете использовать для своих xml-макетов
style="@style/TextView.Example"
Ответ 6
<?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>
вы пытаетесь применить пространство имен XML к значению атрибута, которое не будет работать. В этом случае вы должны указать имя пакета напрямую, например:
<style name="my_style"> <item name="com.my.project:tag">some_value</item> </style>
Ответ 7
Быстрое решение через код!
String pathFont = "fonts/ReallyCoolFont.ttf";
TextView text = (TextView) findViewById(R.id.TextView1);
Typeface fontFace = Typeface.createFromAsset( getAssets(), pathFont );
text.setTypeface( fontFace );
Сторонние библиотеки, решите проблему в XML!
1 - https://github.com/leok7v/android-textview-custom-fonts
2 - https://github.com/ragunathjawahar/android-typeface-textview
Мое предложение
У вас будут другие потребности, и для каждого компонента
вам придется настроить класс.
Другая проблема: у вас есть другие макеты и N TextView компоненты
для обслуживания у вас будет много работы.
Я использую этот метод в проектах в OnCreate моей деятельности
если мне нужно изменить шрифт, я должен это сделать
только в методе OnCreate для каждого вида деятельности.
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) );
Ответ 8
Пользовательские атрибуты определяются с помощью тегов <declare-styleable>
; обычно файл называется attrs.xml. В объявлении пространства имен будет указано ваше имя пакета приложения.
Весь процесс описан здесь: Создание класса просмотра | Разработчики Android