Как объявить несколько стилизованных атрибутов с одинаковым именем для разных тегов?

Я хочу, чтобы мой 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);

Как я могу это решить?


person Andreas    schedule 16.09.2013    source источник
comment
Аналогично stackoverflow.com/questions/4434327/   -  person Suragch    schedule 18.02.2017


Ответы (4)


Ссылка, которую вы разместили, дает вам правильный ответ. Вот что он предлагает вам сделать:

<?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оба доступны.

Если у вас есть возможность, прочитайте этот ответ: Link. Соответствующая цитата:

Вы можете определить атрибуты в верхнем элементе или внутри элемента. Если я собираюсь использовать атрибут более чем в одном месте, я помещаю его в корневой элемент.

person Vikram    schedule 19.09.2013
comment
Это больше не похоже на правду (или, по крайней мере, при использовании Android Studio 2.3). Когда я определяю атрибуты в корне, я получаю сообщение об ошибке, говорящее, что эти ресурсы не могут быть разрешены. Я думаю, вам нужно определить родителя с любыми общими атрибутами. - person BioeJD; 16.06.2016

Сделайте это вместо этого. Тег 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.

person Elye    schedule 26.04.2017
comment
Если я правильно понимаю, то тег resources формирует фрейм для наследования, да? Таким образом, атрибут title не будет автоматически унаследован в другом файле, верно? Или я что-то упускаю? Не могли бы вы уточнить это в своем ответе? - person Benjamin Basmaci; 25.03.2019

Вам нужно использовать наследование

<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);
person Biraj Zalavadia    schedule 16.09.2013
comment
Это не работает. Он не генерирует ViewB_title. ViewA_title нельзя использовать для элементов ViewB, так как его идентификатор будет конфликтовать с ViewB_min. - person Andreas; 16.09.2013

<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>

This doesn't work。

<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>

Все в порядке!!

person 有时丶    schedule 13.11.2017