Именованные атрибуты в attrs.xml для пользовательского представления
Я пишу несколько пользовательских представлений, которые имеют одни и те же атрибуты. В соответствующем разделе <declare-styleable>
в attrs.xml
я хотел бы использовать те же имена для атрибутов:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView1">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
...
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
...
</declare-styleable>
</resources>
Я получаю сообщение об ошибке, что myattr1
и myattr2
уже определены. Я обнаружил, что я должен опустить атрибут format
для myattr1
и myattr2
в MyView2
, но если я это сделаю, я получаю следующую ошибку в консоли:
[2010-12-13 23:53:11 - MyProject] ERROR: In <declare-styleable> MyView2, unable to find attribute
Есть ли способ, которым я мог бы это сделать, возможно, какое-то пространство имен (просто гадание)?
Ответы
Ответ 1
Решение: Просто извлеките общие атрибуты из обоих представлений и добавьте их непосредственно в качестве дочерних элементов <resources>
node:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
<declare-styleable name="MyView1">
<attr name="myattr1" />
<attr name="myattr2" />
...
</declare-styleable>
<declare-styleable name="MyView2">
<attr name="myattr1" />
<attr name="myattr2" />
...
</declare-styleable>
</resources>
Ответ 2
Я отправляю этот ответ, поскольку вышеприведенное решение не получилось для меня в андроид-студии. Мне нужно поделиться своими пользовательскими атрибутами среди моих пользовательских представлений, поэтому я попробовал выше решение в студии Android, но не повезло. Поэтому я экспериментирую и делаю способ сделать это. Надеюсь, что это поможет кому-то, кто ищет ту же проблему.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- parent styleable -->
<declare-styleable name="MyView">
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
</declare-styleable>
<!-- inheriting parent styleable -->
<!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myBackgroundColor" format="color"/>
</declare-styleable>
<!-- inheriting parent styleable -->
<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myfont" format="string"/>
...
</declare-styleable>
</resources>
Это работает для меня полностью.
Нам нужно сделать родительский стиль, а затем нам нужно унаследовать родительский стиль. Например, как я сделал выше:
Имя родительского стиля MyView и унаследовало это для моего другого стиля, такого как MyView1 и MyView2 соответственно.
Ответ 3
Как сказал Priya Singhal, Android Studio требует, чтобы имена общих атрибутов определялись в их собственном имени стиля. Они больше не могут быть в корне.
Однако есть еще несколько других замечаний (вот почему я также добавляю ответ):
- Общим стилям не нужно называть то же, что и представление. (Благодаря этому ответу, указав это.)
- Вам не нужно использовать наследование с родителем.
Пример
Вот что я сделал в недавнем проекте, который имеет два пользовательских представления, которые имеют одинаковые атрибуты. Пока пользовательские представления все еще имеют имена для атрибутов и не включают format
, я все равно могу получить к ним доступ, как обычно, из кода.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes to all custom text based views -->
<declare-styleable name="TextAttributes">
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="gravity">
<flag name="top" value="48" />
<flag name="center" value="17" />
<flag name="bottom" value="80" />
</attr>
</declare-styleable>
<!-- custom text views -->
<declare-styleable name="View1">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
<declare-styleable name="View2">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
</resources>
Пример оптимизации
На самом деле, мне даже не нужно указывать атрибуты под настраиваемым именем. Пока я их определяю (дайте им format
) по крайней мере для одного настраиваемого представления, я могу использовать их в любом месте (без format
). Так что это также работает (и выглядит чище):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="View1">
<attr name="text" format="string"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="gravity">
<flag name="top" value="48" />
<flag name="center" value="17" />
<flag name="bottom" value="80" />
</attr>
</declare-styleable>
<declare-styleable name="View2">
<attr name="text"/>
<attr name="textSize"/>
<attr name="textColor"/>
<attr name="gravity"/>
</declare-styleable>
</resources>
Ответ 4
Спасибо Льюис
У меня была та же проблема, и ваше решение наследования дало мне подсказку для этого, как показано ниже, и оно отлично работает. Я только что объявил общие атрибуты выше и снова переписал его в тексте декларации стиля без форматирования.
Я надеюсь, что это поможет кому-то
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- common attributes -->
<attr name="myattr1" format="string" />
<attr name="myattr2" format="dimension" />
<!-- also note "myBackgroundColor" belongs to child styleable"MyView1"-->
<declare-styleable name="MyView1" >
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myBackgroundColor" format="color"/>
</declare-styleable>
<!-- same way here "myfonnt" belongs to child styelable "MyView2" -->
<declare-styleable name="MyView2" parent="MyView">
<attr name="myattr1" />
<attr name="myattr2" />
<attr name="myfont" format="string"/>
...
</declare-styleable>
Ответ 5
На всякий случай кто-то все еще застрял в этой проблеме после того, как попробовал доступное решение. Я застрял с добавлением атрибута subtitle
с форматом string
.
Мое решение - удалить формат.
перед:
<attr name="subtitle" format="string"/>
после
<attr name="subtitle"/>