Как объявить элемент пользовательского интерфейса Android с помощью XML?
xml
android
user-interface
Casebash
источник
источник
Ответы:
В Руководстве для разработчиков Android есть раздел под названием « Создание пользовательских компонентов» . К несчастью, обсуждение атрибутов XML охватывает только объявление элемента управления в файле макета, а не обработку значений внутри инициализации класса. Шаги следующие:
1. Объявите атрибуты в
values\attrs.xml
Обратите внимание на использование неквалифицированного имени в
declare-styleable
теге. Нестандартные атрибуты Android, такие какextraInformation
должны иметь объявленный тип. Теги, объявленные в суперклассе, будут доступны в подклассах без необходимости повторного объявления.2. Создайте конструкторы
Поскольку есть два конструктора, которые используют
AttributeSet
для инициализации, удобно создать отдельный метод инициализации для вызова конструкторов.R.styleable.MyCustomView
это автоматически сгенерированныйint[]
ресурс, где каждый элемент является идентификатором атрибута. Атрибуты генерируются для каждого свойства в XML путем добавления имени атрибута к имени элемента. Например,R.styleable.MyCustomView_android_text
содержитandroid_text
атрибут дляMyCustomView
. Атрибуты могут быть затем получены сTypedArray
использованием различныхget
функций. Если атрибут не определен в определенном в XML,null
возвращается. За исключением, конечно, если возвращаемый тип является примитивом, то в этом случае возвращается второй аргумент.Если вы не хотите получать все атрибуты, вы можете создать этот массив вручную. Идентификатор для стандартных атрибутов Android включен
android.R.attr
, а атрибуты для этого проекта -R.attr
.Обратите внимание, что вы не должны использовать что-либо в
android.R.styleable
соответствии с этой темой это может измениться в будущем. Это все еще в документации, так как полезно просматривать все эти константы в одном месте.3. Используйте его в файлах макета, таких как
layout\main.xml
Включите объявление пространства имен
xmlns:app="http://schemas.android.com/apk/res-auto"
в элемент верхнего уровня xml. Пространства имен предоставляют метод, позволяющий избежать конфликтов, которые иногда возникают, когда разные схемы используют одинаковые имена элементов (дополнительную информацию см. В этой статье ). URL - это просто способ уникальной идентификации схем - на этом URL ничего не нужно размещать . Если кажется, что это ничего не делает, это потому, что вам на самом деле не нужно добавлять префикс пространства имен, если вам не нужно разрешить конфликт.Ссылка на пользовательский вид, используя полное имя.
Образец Android LabelView
Если вы хотите полный пример, посмотрите на образец представления метки Android.
LabelView.java
attrs.xml
custom_view_1.xml
Это содержится в
LinearLayout
с атрибутом пространства имен:xmlns:app="http://schemas.android.com/apk/res-auto"
связи
источник
Отличная ссылка. Спасибо! Дополнение к нему:
Если у вас есть библиотечный проект, в котором объявлены настраиваемые атрибуты для настраиваемого представления, вы должны объявить пространство имен вашего проекта, а не библиотечное. Например:
Учитывая, что в библиотеке есть пакет «com.example.library.customview», а в рабочем проекте есть пакет «com.example.customview», то:
Не будет работать (показывает ошибку «ошибка: не найден идентификатор ресурса для атрибута« newAttr »в пакете« com.example.library.customview »»):
Будет работать:
источник
xmlns:app="http://schemas.android.com/apk/res-auto"
Смотрите комментарий 57 в code.google.com/p/android/issues/detail?id=9656Suspicious namespace: Did you mean http://schemas.android.com/apk/res-auto
res-auto
потому что мы используем Android Studio и Gradle. В противном случае (например, некоторые версии Eclipse) он обычно заканчивается наlib/[your package name]
. то естьhttp://schemas.android.com/apk/lib/[your package name]
Дополнение к наиболее голосуемому ответу.
obtainStyledAttributes ()
Я хочу добавить несколько слов об использовании receiveStyledAttributes (), когда мы создаем пользовательское представление, используя атрибуты android: xxx prdefined. Особенно, когда мы используем TextAppearance.
Как было упомянуто в «2. Создание конструкторов», пользовательское представление получает AttributeSet при его создании. Основное использование мы видим в исходном коде TextView (API 16).
Что мы можем увидеть здесь?
obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
Набор атрибутов обрабатывается по темам в соответствии с документацией. Значения атрибутов составляются шаг за шагом. Сначала атрибуты заполняются из темы, затем значения заменяются значениями из стиля, и, наконец, точные значения из XML для экземпляра специального представления заменяют другие.
Массив запрашиваемых атрибутов -
com.android.internal.R.styleable.TextView
это обычный массив констант. Если мы запрашиваем стандартные атрибуты, мы можем построить этот массив вручную.
Что не упомянуто в документации - порядок следования элементов TypedArray.
Когда в attrs.xml объявляется пользовательское представление, генерируются специальные константы для индексов атрибутов. И мы можем извлечь значения таким образом:
a.getString(R.styleable.MyCustomView_android_text)
. Но для руководстваint[]
нет постоянных. Я полагаю, что getXXXValue (arrayIndex) будет работать нормально.И другой вопрос: «Как мы можем заменить внутренние константы и запросить стандартные атрибуты?» Мы можем использовать значения android.R.attr. *.
Поэтому, если мы хотим использовать стандартный атрибут TextAppearance в пользовательском представлении и читать его значения в конструкторе, мы можем изменить код из TextView следующим образом:
Где CustomLabel определяется:
Возможно, я как-то ошибаюсь, но документация Android для receiveStyledAttributes () очень плохая.
Расширение стандартного компонента пользовательского интерфейса
В то же время мы можем просто расширить стандартный компонент пользовательского интерфейса, используя все его объявленные атрибуты. Этот подход не очень хорош, потому что TextView, например, объявляет много свойств. И будет невозможно реализовать полную функциональность в переопределенных onMeasure () и onDraw ().
Но мы можем пожертвовать теоретическим широким использованием пользовательского компонента. Скажите «Я точно знаю, какие функции я буду использовать», и не делитесь ни с кем кодом.
Тогда мы можем реализовать конструктор
CustomComponent(Context, AttributeSet, defStyle)
. После вызоваsuper(...)
все атрибуты будут проанализированы и доступны через методы получения.источник
Похоже, что Google обновил свою страницу для разработчиков и добавил туда различные тренинги.
Один из них посвящен созданию пользовательских видов и может быть найден здесь
источник
Большое спасибо за первый ответ.
Что касается меня, у меня была только одна проблема с этим. Раздувая мой взгляд, у меня была ошибка: java.lang.NoSuchMethodException: MyView (Context, Attributes)
Я решил это, создав новый конструктор:
Надеюсь, это поможет!
источник
Вы можете включить любой файл макета в другой файл макета, как
здесь файлы макета в теге include - это другие файлы макета .xml в той же папке res.
источник