Как объявить несколько стилируемых атрибутов с тем же именем для разных тегов?
Я хочу, чтобы оба объекта ViewA и ViewB имели тег "title". Но я не могу поместить это в attrs.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ViewA">
<attr name="title" format="string" />
</declare-styleable>
<declare-styleable name="ViewB">
<attr name="title" format="string" />
<attr name="max" format="integer" />
</declare-styleable>
</resources>
из-за ошибки Атрибут "title" уже определен. Другой вопрос показывает это решение:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="title" format="string" />
<declare-styleable name="ViewB">
<attr name="max" format="integer" />
</declare-styleable>
</resources>
но в этом случае R.styleable.ViewA_title
и R.styleable.ViewB_title
не генерируются. Мне нужны они для чтения атрибутов из AttributeSet, используя следующий код:
TypedArray a=getContext().obtainStyledAttributes( as, R.styleable.ViewA);
String title = a.getString(R.styleable.ViewA_title);
Как я могу это решить?
Ответы
Ответ 1
Ссылка, которую вы опубликовали, дает правильный ответ. Это то, что вы предлагаете:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="title" format="string" />
<declare-styleable name="ViewA">
<attr name="title" />
</declare-styleable>
<declare-styleable name="ViewB">
<attr name="title" />
<attr name="max" format="integer" />
</declare-styleable>
</resources>
Теперь доступны R.styleable.ViewA_title
и R.styleable.ViewB_title
.
Если у вас есть шанс, прочитайте этот ответ: Ссылка. Соответствующая цитата:
Вы можете определить атрибуты в верхнем элементе или внутри элемент. Если я собираюсь использовать attr в более чем одно место, которое я помещаю в корневой элемент.
Ответ 2
Вам нужно использовать наследование
<resources>
<declare-styleable name="ViewA">
<attr name="title" format="string" />
</declare-styleable>
<declare-styleable name="ViewB" parent="ViewA"> // inherit from ViewA
<attr name="min" format="integer" />
<attr name="max" format="integer" />
</declare-styleable>
</resources>
В вашем java-коде
String namespace = "http://schemas.android.com/apk/res/" + getContext().getPackageName();
int title_resource = attrs.getAttributeResourceValue(namespace, "title", 0);
String title = "";
if(title_resource!=0){
title = getContext().getString(title_resource);
}
int min = attrs.getAttributeResourceValue(namespace, "min", 0); // read int value
int max = attrs.getAttributeResourceValue(namespace, "max", 0);
Ответ 3
Сделайте это вместо этого. Нет тега parent
<resources>
<declare-styleable name="ViewA">
<attr name="title" format="string" />
</declare-styleable>
<declare-styleable name="ViewB" >
<attr name="title" />
<attr name="min" format="integer" />
<attr name="max" format="integer" />
</declare-styleable>
</resources>
Это связано с тем, что однажды title
объявлен в ViewA
, ему не нужно (а также не может) быть объявлено снова в другом declare-styleable
Ответ 4
<resources>
<declare-styleable name="ViewA">
<attr name="title" format="string" />
</declare-styleable>
<declare-styleable name="ViewB" parent="ViewA"> // inherit from ViewA
<attr name="min" format="integer" />
<attr name="max" format="integer" />
</declare-styleable>
Это не работает.
<resources>
<attr name="title" format="string" />
<declare-styleable name="ViewA">
<attr name="title" />
</declare-styleable>
<declare-styleable name="ViewB">
<attr name="title" />
<attr name="max" format="integer" />
</declare-styleable>
Это также не работает.
<resources>
<declare-styleable name="ViewA">
<attr name="title" format="string" />
</declare-styleable>
<declare-styleable name="ViewB" >
<attr name="title" />
<attr name="min" format="integer" />
<attr name="max" format="integer" />
</declare-styleable>
Это было нормально!