Именованные атрибуты в 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"/>