Объявление атрибутов стиля в Android



там очень мало документации о declare-styleable тег с помощью которого мы можем объявить пользовательские стили для компонентов. Я нашел этот список допустимых значений для на attr тег. Хотя это хорошо, насколько это возможно, это не объясняет, как использовать некоторые из этих значений. Просмотр attr.xml (источник Android для стандартных атрибутов), я обнаружил, что вы можете делать вещи, как:



<!-- The most prominent text color.  -->
<attr name="textColorPrimary" format="reference|color" />


The format атрибут, очевидно, может быть установлен в комбинацию значений. Предположительно format атрибут помогает синтаксическому анализатору интерпретировать фактическое значение стиля. Затем я обнаружил это в attr.XML-код:



<!-- Default text typeface. -->
<attr name="typeface">
<enum name="normal" value="0" />
<enum name="sans" value="1" />
<enum name="serif" value="2" />
<enum name="monospace" value="3" />
</attr>

<!-- Default text typeface style. -->
<attr name="textStyle">
<flag name="normal" value="0" />
<flag name="bold" value="1" />
<flag name="italic" value="2" />
</attr>


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



Итак, у меня есть два вопроса:




  1. какая разница между атрибутом стиля, который может взять на себя один из наборов enum значения и тот, который может взять на себя набор flag значения?

  2. кто-нибудь знает о какой-либо лучшей документации для how declare-styleable работает (кроме обратного проектирования исходного кода Android)?

993   2  

2 ответов:

вот этот вопрос: определение пользовательских attrs С некоторые информация, но не сильно.

и post . Он имеет хорошую информацию о флагах и перечислениях:

пользовательские флаги атрибутов XML

флаги-это специальные типы атрибутов в что они разрешены только очень небольшое подмножество значений, а именно которые определены ниже тег атрибута. Флаги задаются от атрибут" имя " и " значение" атрибут. Имена обязательны для быть уникальным в пределах этого типа атрибута но ценности не должны быть. Это причина в том, что во время эволюции платформы Android у нас "fill_parent" и "присваиваем" как сопоставление с тем же поведением. Их значения были одинаковыми.

атрибут name сопоставляется с именем используемый в рамках макет XML и не требует префикс пространства имен. Следовательно, для этот "tilingMode" выше я выбрал "центр" как значение атрибута. Я мог бы так же легко выбирается "растянутый" или "повторяется", но больше ничего. Не даже подстановка в фактические значения это было бы позволено.

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

пользовательские перечисления атрибутов XML

перечисления используются в почти идентичном способ как флаги с одним положением, они могут быть использованы взаимозаменяемо с целые. Под капотом перечисления и Целые числа сопоставляются с теми же данными типа, а именно целое число. Когда отображение в определении атрибута с целыми числами перечисления служат для предотвращения "магические числа", которые всегда плохи. Вот почему вы можете иметь "для android:layout_width" с либо размер, целое число или именованная строка "fill_parent."

чтобы поместить это в контекст, давайте предположим, что я создаю пользовательский атрибут "layout_scroll_height", который принимает либо целое число, либо строка "scroll_to_top."Чтобы сделать это, я бы добавил атрибут формата" integer " и следуйте за ним что с перечислением:

<attr name="layout_scroll_height" format="integer">  
    <enum name="scroll_to_top" value="-1"/> 
</attr>

одно условие при использовании перечислений таким образом, что разработчик использование пользовательского представления может целенаправленно место значение "-1" в параметры компоновки. Это вызвать особый случай логики "scroll_to_top."Такие неожиданные (или ожидаемое) поведение может быстро отнесите свою библиотеку к " наследию код " куча, если значения перечисления были выбрали плохо.


как я вижу, реальные значения, которые вы можете добавить в реальности к атрибуту, ограничены тем, что вы можете получить от него. Проверьте AttributeSet ссылка на класс здесь дополнительные полунамеки.

вы можете получить:

  • логические (getAttributeBooleanValue),
  • поплавки (getAttributeFloatValue),
  • ints (getAttributeIntValue),
  • ints (as getAttributeUnsignedIntValue),
  • и строк (getAttributeValue)

ответ@Aleadam очень полезен, но imho он опускает одно важное различие между enum и flag. Первый предназначен для нас, чтобы выбрать одно и только одно значение, когда мы назначаем соответствующий атрибут для некоторого представления. Последние значения могут быть объединены, однако, с помощью побитового оператора OR.

пример, в res/values/attr.xml

<!-- declare myenum attribute -->
<attr name="myenum">
    <enum name="zero" value="0" />
    <enum name="one" value="1" />
    <enum name="two" value="2" />
    <enum name="three" value="3" />
</attr>

<!-- declare myflags attribute -->
<attr name="myflags">
    <flag name="one" value="1" />
    <flag name="two" value="2" />
    <flag name="four" value="4" />
    <flag name="eight" value="8" />
</attr>

<!-- declare our custom widget to be styleable by these attributes -->
<declare-styleable name="com.example.MyWidget">
    <attr name="myenum" />
    <attr name="myflags" />
</declare-styleable>

на res/layout/mylayout.xml теперь мы можем сделать

<com.example.MyWidget
    myenum="two"
    myflags="one|two"
    ... />

таким образом, перечисление выбирает одно из его возможных значений, в то время как флаги могут быть объединены. Числовые значения должны отражать эту разницу, как правило, вы хотите, чтобы последовательность нужно 0,1,2,3,... для перечислений (которые будут использоваться в качестве индексов массива, скажем) и флагов идти 1,2,4,8,... таким образом, они могут быть независимо добавлены или удалены, используя побитовое или | объединить флаги.

мы могли бы явно определить "мета-флаги" со значениями, которые не являются степенью 2, и, таким образом, ввести своего рода стенографию для общих комбинаций. Например, если бы мы включили это в наши myflags декларация

<flag name="three" value="3" />

тогда мы могли бы написать myflags="three" вместо myflags="one|two", для полностью идентичных результатов как 3 == 1|2.

лично мне нравится всегда включают

<flag name="none" value="0" /> <!-- or "normal, "regular", and so on -->
<flag name="all" value="15" /> <!-- 15 == 1|2|4|8 -->

что позволит мне снять или установить все флаги сразу.

более тонко, это может быть так, что один флаг подразумевается другое. Итак, в нашем примере Предположим, что eight флаг, будучи установлен, должен заставить four флаг должен быть установлен (если он уже не было). Тогда мы могли бы переопределить eight предварительно включить, так сказать,four флаг

<flag name="eight" value="12" /> <!-- 12 == 8|4 -->

наконец, если вы объявляете атрибуты в проекте библиотеки, но хотите применить их в макетах другого проекта (в зависимости от lib), вам нужно будет использовать префикс пространства имен, который вы должны связать в корневом элементе XML. Например,

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:auto="http://schemas.android.com/apk/res-auto"
    ... >

    <com.example.MyWidget
        auto:myenum="two"
        auto:myflags="one|two"
        ... />

</RelativeLayout>

Comments

    Ничего не найдено.