Создание класса View

Попробуйте Compose
Jetpack Compose – это рекомендуемый набор инструментов для создания пользовательского интерфейса в Android. Узнайте, как работать с макетами в Compose.

Хорошо спроектированное пользовательское представление похоже на любой другой хорошо спроектированный класс. Он инкапсулирует определенный набор функций с простым интерфейсом, эффективно использует ЦП и память и так далее. Помимо того, что специальное представление должно быть хорошо спроектированным классом, оно должно выполнять следующие действия:

  • Соответствовать стандартам Android.
  • Предоставьте настраиваемые атрибуты, которые работают с макетами XML Android.
  • Отправка событий специальных возможностей.
  • Совместимость с несколькими платформами Android.

Фреймворк Android предоставляет набор базовых классов и XML-тегов, которые помогут вам создать представление, отвечающее всем этим требованиям. В этом уроке рассказывается, как использовать фреймворк Android для создания основных функций класса View.

Дополнительную информацию можно найти в разделе Компоненты пользовательского представления.

Создание подкласса представления

Все классы представлений, определенные в платформе Android, расширяют View. Специальное представление может также расширять View напрямую, или вы можете сэкономить время, расширив один из существующих подклассов представлений, например Button.

Чтобы Android Studio могла взаимодействовать с вашим представлением, вы должны как минимум предоставить конструктор, который принимает объекты Context и AttributeSet в качестве параметров. Этот конструктор позволяет редактору макетов создавать и редактировать экземпляр вашего представления.

Kotlin

class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)

Java

class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

Как задать настраиваемые атрибуты

Чтобы добавить встроенный элемент View в пользовательский интерфейс, укажите его в элементе XML и настройте его внешний вид и поведение с помощью атрибутов элемента. Вы также можете добавлять и настраивать собственные представления с помощью XML. Чтобы включить такое поведение в пользовательском представлении, выполните следующие действия:

  • Определите настраиваемые атрибуты для представления в элементе ресурса <declare-styleable> .
  • Укажите значения атрибутов в макете XML.
  • Получать значения атрибутов во время выполнения.
  • Примените полученные значения атрибутов к представлению.

В этом разделе рассказывается, как определять настраиваемые атрибуты и указывать их значения. В следующем разделе рассказывается, как получать и применять значения во время выполнения.

Чтобы определить настраиваемые атрибуты, добавьте в проект ресурсы <declare-styleable> . Обычно эти ресурсы помещаются в файл res/values/attrs.xml. Пример файла attrs.xml:

<resources>
   <declare-styleable name="PieChart">
       <attr name="showText" format="boolean" />
       <attr name="labelPosition" format="enum">
           <enum name="left" value="0"/>
           <enum name="right" value="1"/>
       </attr>
   </declare-styleable>
</resources>

Этот код объявляет два настраиваемых атрибута, showText и labelPosition, которые принадлежат объекту PieChart, поддерживающему стили. По соглашению название настраиваемого объекта совпадает с названием класса, определяющего пользовательский вид. Следовать этому соглашению необязательно, но многие популярные редакторы кода используют его для автозаполнения.

После определения настраиваемых атрибутов вы можете использовать их в XML-файлах макета так же, как и встроенные атрибуты. Единственное отличие заключается в том, что настраиваемые атрибуты принадлежат к другому пространству имен. Вместо пространства имен http://schemas.android.com/apk/res/android они относятся к http://schemas.android.com/apk/res/[your package name]. Например, вот как использовать атрибуты, определенные для PieChart:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:custom="http://schemas.android.com/apk/res-auto">
 <com.example.customviews.charting.PieChart
     custom:showText="true"
     custom:labelPosition="left" />
</LinearLayout>

Чтобы не повторять длинный URI пространства имен, в примере используется директива xmlns. Эта директива назначает псевдоним custom пространству имен http://schemas.android.com/apk/res/com.example.customviews. Вы можете выбрать любой псевдоним для пространства имен.

Обратите внимание на имя XML-тега, который добавляет пользовательское представление в макет. Это полное имя класса специального представления. Если класс представления является внутренним, укажите также название внешнего класса. Например, класс PieChart содержит внутренний класс PieView. Чтобы использовать настраиваемые атрибуты из этого класса, используйте тег com.example.customviews.charting.PieChart$PieView.

Как применять настраиваемые атрибуты

Когда представление создается из макета XML, все атрибуты в теге XML считываются из пакета ресурсов и передаются в конструктор представления как AttributeSet. Хотя значения можно считывать непосредственно из объекта AttributeSet, у этого подхода есть ряд недостатков:

  • Ссылки на ресурсы в значениях атрибутов не обрабатываются.
  • Стили не применяются.

Вместо этого передайте AttributeSet в obtainStyledAttributes(). Этот метод возвращает массив значений TypedArray, которые уже разыменованы и стилизованы.

Компилятор ресурсов Android выполняет большую часть работы за вас, чтобы упростить вызов obtainStyledAttributes(). Для каждого ресурса <declare-styleable> в каталоге res/ сгенерированный файл R.java определяет массив идентификаторов атрибутов и набор констант, которые определяют индекс для каждого атрибута в массиве. Для чтения атрибутов из TypedArray используются предопределенные константы. Вот как класс PieChart считывает свои атрибуты:

Kotlin

init {
    context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.PieChart,
            0, 0).apply {

        try {
            mShowText = getBoolean(R.styleable.PieChart_showText, false)
            textPos = getInteger(R.styleable.PieChart_labelPosition, 0)
        } finally {
            recycle()
        }
    }
}

Java

public PieChart(Context context, AttributeSet attrs) {
   super(context, attrs);
   TypedArray a = context.getTheme().obtainStyledAttributes(
        attrs,
        R.styleable.PieChart,
        0, 0);

   try {
       mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
       textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
   } finally {
       a.recycle();
   }
}

Обратите внимание, что объекты TypedArray являются общим ресурсом и должны быть утилизированы после использования.

Добавление свойств и событий

Атрибуты – это мощный инструмент для управления поведением и внешним видом представлений, но они могут считываться только при инициализации представления. Чтобы обеспечить динамическое поведение, предоставьте пару методов получения и установки свойств для каждого настраиваемого атрибута. В следующем фрагменте кода показано, как PieChart предоставляет свойство showText:

Kotlin

fun isShowText(): Boolean {
    return mShowText
}

fun setShowText(showText: Boolean) {
    mShowText = showText
    invalidate()
    requestLayout()
}

Java

public boolean isShowText() {
   return mShowText;
}

public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

Обратите внимание, что setShowText вызывает invalidate() и requestLayout(). Эти вызовы необходимы для обеспечения надежной работы представления. Вам необходимо сделать представление недействительным после любого изменения его свойств, которое может изменить его внешний вид, чтобы система знала, что его необходимо перерисовать. Аналогично, если свойство изменяется таким образом, что это может повлиять на размер или форму представления, необходимо запросить новый макет. Если вы забудете вызвать эти методы, могут возникнуть ошибки, которые будет трудно обнаружить.

Специальные представления также должны поддерживать прослушиватели событий, чтобы передавать информацию о важных событиях. Например, PieChart предоставляет специальное событие OnCurrentItemChanged, которое сообщает слушателям, что пользователь повернул круговую диаграмму, чтобы сосредоточиться на новом секторе.

Легко забыть открыть доступ к свойствам и событиям, особенно если вы единственный пользователь специального представления. Тщательно продумав интерфейс представления, вы снизите затраты на его обслуживание в будущем. Рекомендуется всегда предоставлять доступ к свойствам, которые влияют на внешний вид или поведение пользовательского представления.

Дизайн для доступности

Специальный режим просмотра должен поддерживать широкий круг пользователей. в том числе людей с инвалидностью, которая не позволяет им видеть сенсорный экран или пользоваться им. Чтобы обеспечить поддержку пользователей с ограниченными возможностями, сделайте следующее:

  • Добавьте к полям ввода атрибут android:contentDescription.
  • Отправлять события специальных возможностей, вызывая sendAccessibilityEvent(), когда это необходимо.
  • Поддерживайте альтернативные контроллеры, такие как d-pad или трекбол.

Подробнее о том, как сделать приложения более доступными…