- Введение
- Специфические задачи, специфические view
- Создание custom view
- Добавление логики отображения
- Использование полученного view
- Добавление xml атрибутов
- Guide to Android custom views: attributes
- Topics
- Using attributes
- Custom attributes
- Custom layout attributes
- Русские Блоги
- Справочник атрибутов инструментов Android
- 1 Свойства обработки ошибок
- 2 Режим сжатия ресурсов
- 3 Просмотр свойств макета редактора времени разработки
Введение
Это будет серия постов на тему создания пользовательского view компонента для Android. Я покажу как нарисовать содержимое компонента, как работают layouting и measuring, как реализовать view groups и как анимировать содержимое компонента. В этом посте я объясню, как расширить стандартный view, как его использовать и как создать свои собственные xml атрибуты.
Специфические задачи, специфические view
Стандартные view компоненты, которые предоставляет Android, могут использоваться для многих задач и ситуаций. Тем не менее, в наших приложениях наибольшую часть кода часто занимает конфигурация этих view для специфических задач. Этот конфигурационный код часто находится в activity вашего приложения, поэтому их сложно содержать в чистоте. А при наличии большого количества различного кода возникают сложности и с его разделением в отдельные классы.
Предположим, вы работаете над приложением, которое содержит статистику тренировок пользователя. Например, общая дистанция, общее время и так далее, в зависимости от типа тренинга. Для того чтобы отображать данные в удобном виде, вы решили их адаптировать, основываясь на их продолжительности. Если это 2378 секунд, вы хотите отображать это время как «40 минут», а если это 18550 секунд, то лучше было бы отображать на дисплей «5 часов 9 минут».
Создание custom view
Один из способов решения этой задачи — создать специализированный view, который будет должным образом обрабатывать ваш текст. Давайте начнем с создания нашего собственного класса DurationTextView, который будет расширять класс TextView.
TextView, как и все view классы, имеет три различных конструктора: первый просто принимает контекст (Context), второй принимает контекст и набор атрибутов (AttributeSet), а третий еще дополнительно принимает стиль «по умолчанию». В большинстве случаев вам достаточно реализовать второй конструктор, который показан выше.
Теперь мы создали view и чтобы его использовать, мы добавим его в файл разметки:
Обратите внимание, вам необходимо полностью указывать имя вашего класса, который вы реализовали.
В данный момент этот класс практически идентичен стандартному TextView, поэтому давайте добавим ему некоторую функциональность.
Добавление логики отображения
Поскольку этот view будет отображать длительность, давайте добавим метод setDuration().
Что делает этот метод? Он получает значение длительности, переводит его в текстовую строку в определенном формате, используя некую логику, а затем выводит с помощью метода setText(). В данном случае логика заключается в переводе секунд в минуты и дальнейшем разделении на часы и минуты. Также в методе присутствует логика для корректного отображения одной минуты: «1 minute» вместо «1 minute(s)».
В конце метода отформатированное время преобразуется в строку с помощью шаблона.
private static final String TEMPLATE = «Duration: %s«;
Шаблон начинается со слова «Duration», а далее жирными буквами отображается отформатированная строка.
Для простоты я использовал в коде строковые литералы. В нормальном коде, эти строковые литералы лучше перенести в strings.xml, это позволяет в дальнейшем локализовать их.
Использование полученного view
Попробуем использовать наш view. В xml файл разметки добавим 5 custom View.
А в activity в методе onCreate() после метода setContentView() добавим следующие строки.
Соберем проект и загрузим его в эмулятор. Полученный результат можно видеть на изображении ниже.
Добавление xml атрибутов
Если бы мы могли задавать шаблон, то созданный нами компонент был бы более универсальным. По идее можно добавить метод, который позволит нам устанавливать шаблон, однако это не так просто. Если подумать, длительности нам нужно устанавливать динамически, а шаблон скорее всего будет все время одинаковым. Поэтому вместо метода, давайте добавим нашему custom view новые xml атрибуты.
В первую очередь нужно создать в папке values файл attrs.xml, где мы сможем определить атрибуты. Для этого view мы добавим один атрибут — template типа string. Выглядеть это будет так:
Мы записали тег declare-styleable и задали имя TemplateTextView. Имя может быть произвольным, но обычно задают имя, совпадающее с именем view. В данном случае я не задаю имя DurationTextView, потому что планирую использовать template атрибут еще в другом view.
Далее мы определили новый атрибут, установив ему имя template и формат string. Помимо string существует множество других форматов, например, Color, Integer, Boolean, Reference и так далее.
Использовать новый атрибут в layout xml можно так.
Обратите внимание, в корневом элементе мы добавляем такую строчку.
xmlns:app= «http://schemas.android.com/apk/res-auto»
Это позволяет нам использовать атрибуты, которые определены в файле attrs.xml, в нашем layout. В данном случае мы задали префикс «app», хотя он может быть произвольным.
Для того чтобы использовать новый атрибут, нужно получить его значение в нашем custom view. Сначала заменяем приватную статическую константу «TEMPLATE» переменной «template». Затем добавляем в наш конструктор следующий код.
В первой строке мы получаем набор атрибутов, который содержит все атрибуты, существующие в xml файле. Метод obtainStyledAttributes() делает две основные вещи. Во-первых, он фильтрует все атрибуты из attrs с помощью контекста, применяет стили и resolves reference to values. Во-вторых, он возвращает только те атрибуты, которые вы определили. Они задаются вторым аргументом, который представляет собой массив ссылок на требуемые атрибуты. В данном случае в R.styleable.TemplateTextView у нас только один атрибут R.attr.template, который мы создали в файле attrs.xml.
Далее мы используем массив attributes, чтобы получить значение атрибута. Если значение шаблона не было определено или не содержит «%s», мы устанавливаем template = «%s». И в заключении нужно не забыть освободить ресурсы с помощью функции recycle().
После некоторых изменений в layout, приложение будет выглядеть так:
Здесь я установил шаблон для первых трех custom view
Большая часть view в Android имеет методы, которые позволяют устанавливать значения XML атрибутов в коде. Возможно вам тоже понадобиться добавить какой-нибудь метод, это зависит от того, как вы будете использовать view.
В следующей части мы посмотрим как нарисовать свой собственное содержимое view компонента и сделаем view для отображения графика.
Исходники к статье можно скачать c GitHub.
По материалам сайта Jayway
Вольный перевод — Pavel Bobkov.
Источник
Guide to Android custom views: attributes
Jan 7, 2020 · 5 min read
I’ve been designing, writing and publishing Android custom views for the past 5 years now. I guess it’s about time to sum it up and share the results.
The article series here, on Medium, is a copy of materials published on my repository, which you can find under the following link: https://github.com/ZieIony/GuideToCustomViews. There you can also find case studies, issues and my other projects including custom views.
Topics
Using attributes
Each style uses attributes to provide values to views. Here’s an example XML with a view declaration:
The enclosing la y out is invalid because it needs at least layout_width and layout_height attributes to be parsed correctly. Let’s forget about for the sake of simplicity. This view has an inline style with four attributes:
- style=»@style/ImageView.Icon» — style attribute is a special attribute parsed by the framework. It’s used to change apply a style defined in an external XML file. There’s a couple of special tags and attributes without any prefixes: layout , fragment , include , data and probably a couple more.
- android:layout_width/_height=»wrap_content» — attribute usages prefixed with android are defined by the Android framework. You can reuse them in your custom views if you wish. Attribute names prefixed with layout_ by convention are used by enclosing layouts. You can learn how to add your own layout attributes here. wrap_content is an enum — one of many types of attributes. Attributes can reference values, resources, styles and many more.
- app:srcCompat=»@drawable/ic_airplanemode_on_24px» — this is an attribute added by a library. The app prefix is declared somewhere in the layout and can have any name. srcCompat is an attribute of type drawable and is used here to add support for vector drawables. It references a file from res/drawable folder.
This view is enclosed in layout tag — it’s a data binding declaration. This tag has some special meaning and features.
- This view also uses layout_width and layout_height , but this time with values of type dimension . The dp means that the value is expressed in device independent pixels. Some of the attributes have more than one type.
- guide_htmlText=»Select Dates» — this is a library attribute and is used without any namespace prefix. It’s a data binding attribute handled by a binding adapter.
- android:textColor=»?android:attr/textColorPrimary» — this attribute has a theme reference value. The question mark starts a theme reference. The android: part is a namespace and is empty for custom attributes. The attr/textColorPrimary part declares an attribute present in the current theme to take a value from.
- android:textAppearance=»@style/TextAppearance.Body1″ — a framework’s attribute of reference type. Is used to change text style of text views. Here it references a style resource of name TextAppearance.Body1`.
Resources are a very broad topic. Even a very simple application usually needs at least a theme, a couple of drawables (icons) and uses styles and colors declared somewhere. Read more about resources on developer.android.com.
Custom attributes
First thing to do to add a custom attribute is to declare a styleable in XML. A styleable is an XML with a bunch of attributes that will be used by a custom view.
You will also need an attribute for the styleable to use. You can either add your own attribute (remember to prefix it) or reuse an existing one. Your attributes can be declared and then used in a styleable or declared and used at once. Reusing attributes is just as easy — just remember to use the same namespace, name and type as the original declaration.
For a custom view, you may want to add a theme attribute. That attribute will be used by the view to read the default style provided by a theme. It’s just a simple reference attribute, usually with a style suffix.
You also need a style. It can be a base style (if it’s a completely new style) or a derived style (if there was a parent style you could use).
Then declare a theme in themes.xml and use the style attribute to set the style.
The attributes are passed to a view in a couple of ways:
- Using base theme values.
- Using a default style resource. This way corresponds to the 4th parameter in the 4-parameter constructor and the 4th parameter in obtainStyledAttributes() . It’s a reference to the default style for a view. If this value is 0, it won’t be used to look for defaults.
- Style using the theme attribute. This way corresponds to the 3rd parameter in the 3 and 4-parameter constructors and the 3rd parameter in obtainStyledAttributes() . It’s a reference to a style specified in the current theme. If this value is 0, it won’t be used to look for defaults.
- Style using the style attribute and using inline attribute usage in a layout. These come in AttributeSet attrs . Can be null if the view was created without using an XML layout.
- Default values applied when grabbing attribute values from value arrays.
In a typical case, you need only two constructors and a bit of initialization code. obtainStyledAttributes() is used to get an array of values for this view considering default style, the current theme and XML attributes. Then, attribute by attribute, you have to get a value by id and set it to the view. Notice how the attribute names declared in XML (with namespaces) are transformed to field names of the ids in the example.
Custom layout attributes
LayoutParams classes have their own style attributes. You can spot them in layout XMLs. The following button has four inline style attributes. android:text is used by the Button class. The rest of the attributes (starting with layout_) is used by LayoutParams classes — android:layout_width and android:layout_height by plain LayoutParams and android:layout_margin by MarginLayoutParams.
Adding custom layout attributes is very similar to adding custom view attributes. You also need to declare attributes, a styleable, read the attributes using obtainStyledAttributes() and the value getters, etc. Only the place, where all of that attribute parsing and storing happens is different.
By convention layout styleables are named after the owning layout with _ Layout suffix. I like to also add _ layout prefix to attributes’ names. The rest is identical to the usual styleables.
LayoutParams usually are implemented as static classes inside their owning layouts. The most interesting part of a LayoutParams class is the XML constructor — very similar to views’ XML constructors. The attrs parameter contains values of style attributes. You can get the layout style attributes from there. Complete example code can be found here.
For the layout to use the new LayoutParams class you have to override a couple of methods:
Источник
Русские Блоги
Справочник атрибутов инструментов Android
Используя пространство имен инструментов, android studio поддерживает множество атрибутов XML, которые будут удалены при сборке приложения без какого-либо влияния на размер APK и поведение во время выполнения. Посмотри пожалуйстаОфициальный сайт。
Атрибуты инструментов можно условно разделить на три категории: 1. Атрибуты обработки ошибок, которые будут влиять на запросы Lint, 2. Атрибуты сокращения ресурсов, которые влияют на сжатие ресурсов, 3. Просмотр атрибутов во время разработки редактора макета.
1 Свойства обработки ошибок
Любой элемент может использовать этот атрибут, например, строковый элемент в strings.xml, мы можем игнорировать неправильный атрибут MissingTranslation:
В другом примере для элемента ImageView в следующем коде, если мы не добавим атрибут tools: ignore, Lint предложит, чтобы в ImageView отсутствовал атрибут android: contentDescription, а tools: ignore = «contentDescription» может игнорировать это предупреждение:
Любой элемент может использовать этот атрибут, это и аннотации в коде Java@TargetApiЭто то же самое: оно определяет уровень API, поддерживаемый текущим элементом, а значение атрибута может быть числом или кодовым именем.
В этом случае, даже если указано minSdkVersion Если текущий элемент не поддерживается, Lint не будет предупреждать. Такие как набор minSdkVersion=12 , Но использовать GridLayout Если вам нужно добавить tools:targetApi=»14″ :
Только тег ресурсов может использовать этот атрибут. Язык и регион ресурсов по умолчанию — английский, и будет выполнена проверка правописания. Этот атрибут указывает язык и регион ресурсов. Конечно, значение атрибута должно быть допустимым.locale qualifier。
Например, вы можете указать values/strings.xml Язык файла по умолчанию — испанский вместо английского:
2 Режим сжатия ресурсов
Когда используешьresource shrinkingПри следующих атрибутах указываются некоторые характеристики сжатия ресурсов.
Чтобы использовать сжатие ресурсов, пожалуйста, build.gradle файл shrinkResources Приписывать true ,( minifyEnabled Атрибут сокращает код):
Подходящее: , Укажите, использовать ли безопасный режим или строгий режим при сборке. В безопасном режиме резервируются все ресурсы, на которые имеются прямые ссылки, и ресурсы, которые могут использоваться динамически, такие какResources.getIdentifier()Ресурс, вызываемый методом. Строгий режим сохраняет только ресурсы с прямой ссылкой.
Режим безопасности по умолчанию shrinkMode=»safe» , Если вы хотите использовать строгий режим, вы можете использовать следующий код:
Если включен строгий режим, вы можете настроить ресурсы для сохранения. Если вы хотите сохранить или отменить определенные ресурсы, создайте файл XML, содержащий тег в вашем проекте, и укажите каждый из них в инструментах: атрибут keep Ресурсы, которые должны быть зарезервированы, укажите каждый ресурс, который нужно удалить, в атрибуте tools: discard. Оба эти атрибута принимают разделенный запятыми список имен ресурсов. Вы можете использовать символ звездочки в качестве подстановочного знака. Например:
Сохраните файл в ресурсах проекта, например, в res / raw / keep.xml. Сборка не упаковывает файл в APK.
Для получения дополнительной информации, пожалуйста, смотрите:Shrink your resources。
Подходящее: метка. Этот атрибут может резервировать определенные ресурсы, такие какResources.getIdentifier()) Динамически используемые ресурсы. Использование может быть создано res/raw/keep.xml Содержание файла выглядит следующим образом:
Подходящее: метка. На некоторые ресурсы можно ссылаться, но они не влияют на приложение. Эти ресурсы нельзя удалить напрямую, тогда это свойство может удалить эти ресурсы, или плагин Gradle неверно определит, что на эти ресурсы ссылаются, тогда это свойство также можно использовать. Использование заключается в следующем:
3 Просмотр свойств макета редактора времени разработки
- инструменты: заменить андроид:
Инструменты могут охватывать все атрибуты Android. Я считаю, что это тот, который все использовали больше всего, поэтому я не буду об этом говорить.
Android studio2.2 добавил этот атрибут, чтобы указать тип макета тега слияния, например:
Только корневой вид может использовать этот атрибут. Он определяет, с каким действием текущий макет связан с текущим макетом по умолчанию, так что макет может получить некоторую информацию об этом действии, такую как тема, используемая действием, и т. Д., А также при использовании быстрого исправления (сочетание клавиш на компьютере Mac + enter) При добавлении события onClick в дочерний View соответствующий код метода будет вставлен в Activity.
Только RecyclerView может использовать это свойство. Моя версия Android Studio 3.0.1, количество отображаемых RecyclerView по умолчанию в редакторе макетов равно 10. Этот атрибут может изменить количество отображений RecyclerView.
Только атрибут фрагмента может использовать этот атрибут, и стиль макета можно предварительно просмотреть в окне предварительного просмотра.
- tools:listitem / tools:listheader / tools:listfooter
Только AdapterView может использовать это свойство, которое определяет расположение элементов, верхний и нижний колонтитулы списка, но также можно использовать свойство tools: listitem RecyclerView:
Применимый объект: быть Любой корневой вид ссылается:
Применимый объект: корень , Сообщите IDE, какое меню использовать в окне предварительного просмотра, и это меню будет отображаться в корневом узле макета (положение панели действий).
Окно предварительного просмотра очень умное. Если макет связан с действием (заданным с помощью tools: context), он автоматически запросит метод onCreateOptionsMenu этого действия, чтобы отобразить меню, и свойство tools: menu может переопределить это поведение по умолчанию.
Значением атрибута является идентификатор меню, и их может быть больше 1. Различные идентификаторы меню разделяются запятыми.
Следует отметить, что когда тема является Theme.AppCompat, это свойство не работает.
Укажите режим отображения панели действий, его значение может быть: 1. стандартное, 2. вкладки, 3. список
Точно так же, когда тема — Theme.AppCompat (r21 +, как минимум) или Theme.Material, или макет включает в себя панель инструментов. Этот атрибут тоже не работает, работает только голографическая тема.ссылка
- tools:minValue / tools:maxValue
Подходящее: NumberPicker , Предварительный просмотр максимальных и минимальных значений NumberPicker, но не вступать в силу. MaxValue и minValue NumberPicker могут быть установлены только по коду, если вы хотите установить его с помощью xml, вам нужно найти другой способ, здесьссылка, Почему xml из android studio не поддерживает установку этих двух атрибутов? Я не понимаю, пожалуйста, оставьте сообщение, чтобы сообщить мне.
Подходящее: , Позвольте DrawerLayout открыть направление.
Constant | Value | Description |
---|---|---|
end | 800005 | Push object to the end of its container, not changing its size. |
left | 3 | Push object to the left of its container, not changing its size. |
right | 5 | Push object to the right of its container, not changing its size. |
start | 800003 | Push object to the beginning of its container, not changing its size. |
- «@tools:sample/*» resources
Применимые объекты: все представления, поддерживающие текст и изображения. Этот атрибут эквивалентен добавлению заполнителя в представление, например:
В следующей таблице описаны все заполнители, которые можно использовать для просмотра:
Attribute value | Description of placeholder data |
---|---|
@tools:sample/full_names | Full names that are randomly generated from the combination of @tools:sample/first_names and @tools:sample/last_names. |
@tools:sample/first_names | Common first names. |
@tools:sample/last_names | Common last names. |
@tools:sample/cities | Names of cities from across the world. |
@tools:sample/us_zipcodes | Randomly generated US zipcodes. |
@tools:sample/us_phones | Randomly generated phone numbers with the following format: (800) 555-xxxx. |
@tools:sample/lorem/random | Placeholder text that is derived from Latin. |
@tools:sample/date/day_of_week | Randomized dates and times for the specified format. |
@tools:sample/date/ddmmyy | То же, что и выше |
@tools:sample/date/mmddyy | То же, что и выше |
@tools:sample/date/hhmm | То же, что и выше |
@tools:sample/date/hhmmss | То же, что и выше |
@tools:sample/avatars | Vector drawables that you can use as profile avatars. |
@tools:sample/backgrounds/scenic | Images that you can use as backgrounds. |
Эти ресурсы-заполнители не будут включены в пакет APK, поэтому не беспокойтесь об увеличении размера приложения, просто проверьте эффект предварительного просмотра в окне предварительного просмотра.
Вот два примера.
Например, следующий код определяет RecyclerView, его tools:listitem=»@layout/item_part1″ :
Источник