Рисование собственных представлений (View) в Android
Получите полный контроль над представлением и оптимизируйте его производительность
В преддверии старта курса «Android Developer. Professional» приглашаем всех желающих принять участие в открытом вебинаре на тему «Пишем gradle plugin».
А пока делимся переводом полезного материала.
Введение
Разработчики постоянно проектируют различные виды пользовательских интерфейсов с помощью XML, но в дополнение к этому можно довольно легко освоить создание собственных представлений, которые открывают новые преимущества и позволяют избежать повторного использования шаблонного кода.
В Android доступен широкий набор готовых виджетов и макетов для создания пользовательского интерфейса, однако они не могут удовлетворить все требования наших приложений. И здесь на помощь приходит возможность создания собственных представлений. Создав собственный подкласс представления, можно получить максимально полный контроль за внешним видом и функционалом экранного элемента.
Прежде чем приниматься за работу с собственными представлениями, полезно изучить жизненный цикл представления.
Зачем создавать собственные представления?
Чтобы реализовать собственное представление, в большинстве случаев понадобится больше времени, чем если использовать обычные представления. Создавать собственные представления стоит лишь в том случае, если нет другого, более простого способа реализовать нужную вам возможность или если у вас есть какие-либо из указанных ниже проблем, которые можно устранить за счет создания собственного представления.
Производительность: в вашем макете много представлений и вы хотите оптимизировать их, нарисовав одно, более легкое собственное представление.
Имеется сложная иерархия представлений, которую трудно использовать и поддерживать.
Необходимо создать специализированное представление, требующее рисования вручную.
Общий подход
Чтобы приступить к созданию компонентов для реализации собственных представлений, необходимо выполнить следующие основные шаги.
Создать класс, расширяющий базовый класс или подкласс представления.
Реализовать конструкторы, использующие атрибуты из XML-файла.
Переопределить некоторые методы родительского класса (onDraw(), onMeasure() и т. д.) в соответствии с нашими требованиями.
После выполнения этих шагов созданный расширяющий класс можно использовать вместо представления, на основе которого он был создан.
Пример
В одном из моих проектов мне нужно было создать круглый виджет TextView для отображения количества уведомлений. Чтобы достичь этой цели, нужно создать подкласс TextView.
Шаг 1. Создадим класс с именем CircularTextView .
Шаг 2. Расширим класс виджета TextView. Здесь под TextView в IDE выдается ошибка, в которой сообщается, что у этого типа есть конструктор и он должен быть инициализирован.
Шаг 3. Добавим конструкторы в класс.
Это можно сделать двумя способами.
Первый способ добавления конструкторов в класс показан ниже.
Другой способ заключается в добавлении аннотации @JvmOverloads к вызову конструктора, как показано ниже.
Часто нас сбивает с толку то, что у представления есть несколько разных типов конструкторов.
View(Context context)
Простой конструктор для динамического создания представления из программного кода. Здесь параметр context — это контекст, в котором работает представление и через который можно получить доступ к текущей теме, ресурсам и т. д.
View(Context context, @Nullable AttributeSet attrs)
Конструктор, который вызывается при формировании представления из XML-файла. Он вызывается, когда представление создается из XML-файла, содержащего атрибуты представления. В этом варианте конструктора используется стиль по умолчанию (0), поэтому применяются только те значения атрибутов, которые есть в теме контекста и заданном наборе AttributeSet .
Шаг 4. Самый важный шаг в отрисовке собственного представления — это переопределение метода onDraw() и реализация необходимой логики отрисовки внутри этого метода.
Метод OnDraw (canvas: Canvas?) имеет параметр Canvas (холст), с помощью которого компонент представления может отрисовывать себя. Для рисования на холсте необходимо создать объект Paint.
Как правило, процесс рисования определяется двумя аспектами:
что рисовать (определяется объектом Canvas);
как рисовать (определяется объектом Paint).
Например, Canvas предоставляет метод для рисования линии, а Paint предоставляет методы для определения цвета этой линии. В нашем случае объект Canvas в классе CircularTextView предоставляет метод для рисования окружности, а объект Paint заполняет ее цветом. Проще говоря, Canvas определяет, какие фигуры можно нарисовать на экране, а Paint определяет свойства нарисованных фигур — цвет, стиль, шрифт и т. д.
Давайте займемся кодом. Мы создаем объект Paint и присваиваем ему некоторые свойства, а затем рисуем фигуру на холсте (объект Canvas), используя наш объект Paint. Метод onDraw() будет выглядеть так:
IDE показывает предупреждение о том, что следует избегать выделения объектов во время операций отрисовки или операций с макетом. Это предупреждение возникает потому, что метод onDraw() много раз вызывается при отрисовке представления, в котором каждый раз создаются ненужные объекты. Поэтому, чтобы избежать ненужного создания объектов, мы вынесем соответствующую часть кода за пределы метода onDraw() , как показано ниже.
При выполнении отрисовки всегда помните о том, что следует повторно использовать объекты вместо создания новых. Ваша IDE может указать на потенциальные проблемы, но полагаться на нее не стоит. Например, она не сможет отследить случай, когда объекты создаются внутри методов, вызываемых из метода onDraw() . Поэтому лучше проверять все самостоятельно.
Шаг 5. Мы закончили с рисованием. Теперь давайте внесем этот класс представления в XML.
Добавьте этот XML-макет в вашу активность (Activity) и запустите приложение. Вот что будет на экране.
Выглядит неплохо, правда? Теперь сделаем так, чтобы значение динамическому свойству цвета в circlePaint назначалось из активности, а также добавим контур к кружку. Для этого в классе CircularTextView необходимо создать несколько методов-сеттеров, чтобы можно было вызывать эти методы и устанавливать свойства динамически.
Для начала давайте реализуем настройку цвета отрисовки. Для этого создадим сеттер, как показано ниже.
Теперь мы можем устанавливать цвет из нашей активности динамически, вызывая этот метод.
Неплохо, правда? Теперь давайте добавим контур к кружку. Контур будет задаваться двумя входными параметрами: шириной линии контура и ее цветом. Чтобы задать цвет линии контура, нам нужно создать объект Paint точно так же, как мы это делали для кружка. Чтобы задать ширину линии контура, мы создадим переменную, установим для нее нужное значение и используем его в методе onDraw() . Полный код будет выглядеть так:
Теперь в активности можно динамически настраивать эти атрибуты нужным образом.
Далее давайте запустим приложение, устанавливая различные цвета для нашего виджета.
Итак, теперь стало ясно, как динамически устанавливать свойства из активности, но возникает вопрос о том, как устанавливать атрибуты из XML. Продолжим наше исследование.
Для начала создадим файл с именем attrs.xml в папке values. Этот файл будет содержать все атрибуты для различных представлений, которые мы создаем сами. В приведенном ниже примере у нашего представления под названием CircularTextView имеется атрибут ct_circle_fill_color , который принимает значение цвета. Аналогичным образом мы можем добавить и другие атрибуты.
Затем нам нужно будет прочитать эти свойства в классе, который мы создали для реализации собственного представления. В блоке инициализации мы считываем набор атрибутов, как показано ниже.
Теперь просто переходим к XML-макету и устанавливаем значение свойства, соответствующее нужному цвету, после чего запускаем приложение. На выходе мы увидим нужный результат.
В моем случае результат был таким:
Примечание. При рисовании не задавайте жестко размер вашего представления, так как им могут воспользоваться другие разработчики с применением других размеров. Рисуйте представление в соответствии с его текущим размером.
Обновление представления
Итак, мы задали собственное представление. Если мы хотим обновлять представление при изменении какого-нибудь свойства или по какой-то другой причине, этого можно добиться двумя основными способами.
invalidate()
invalidate() — это метод, который инициирует принудительную перерисовку определенного представления. Проще говоря, метод invalidate() следует вызывать в случае, когда требуется изменение внешнего вида представления.
requestLayout()
Если в какой-то момент происходит изменение состояния представления, то метод requestLayout() сообщает системе представлений, что необходимо сделать перерасчет фаз «измерение» (Measure) и «макет» (Layout) для данного представления (измерение → макет → рисование). Проще говоря, метод requestLayout() следует вызывать в случае, когда требуется изменение границ представления.
Теперь, я надеюсь, вы знаете в общих чертах, как создавать собственные представления. Чтобы они демонстрировали отличную производительность, необходимо освоить все описанные здесь методы.
Источник
Где находится предварительный просмотр макета Android Studio?
Я установил Android Studio, но когда я редактирую файлы макета, я не могу найти предварительный просмотр в прямом эфире! Я просто вижу XML-файл. Как я могу видеть мой макет в графическом представлении?
Обновление: так выглядит в моем случае:
У вас должна быть кнопка « Design рядом с кнопкой « Text в текстовом редакторе xml:
Или вы можете использовать кнопку Preview в правом верхнем углу, чтобы добавить окно предварительного просмотра рядом с кодом XML:
ОБНОВИТЬ:
Если у вас его нет, сделайте следующее: View -> Tool Windows -> Preview
Похоже, что у некоторых людей такая же проблема. Проблема в том, что в среде IDE отображается только предварительный просмотр, если вы редактируете файл макета в каталоге res/layout* проекта Android.
В частности, он не будет показывать, если редактирование файла в build/res/layout* поскольку они не являются исходным каталогом, а выходным каталогом. В вашем случае вы редактируете файл в каталоге build/ …
Папка «Ресурс» устанавливается автоматически и может быть просмотрена (и изменена) в разделе «Структура проекта»> «Модули»> «Имя модуля»> «Android»> «Каталог ресурсов».
В случае, если это помогает кому-либо, у меня была такая же проблема сегодня, когда отсутствовали вкладки «дизайн / текст». Я переключился на темную тему и подумал, что это проблема, поэтому вернулась к настройкам / внешнему виду (в настройках IDE), переключилась на тему по умолчанию, и это верно для меня. Я также мог бы снова переключиться на тему Darcula, и вкладки все еще были там, поэтому похоже, что темы переключения – это способ сбросить окна / вкладки IDE.
Выберите файл MainActivity.java из левой панели, как показано на красном прямоугольнике.
Щелкните левой кнопкой мыши значок XML-тега, как показано красным цветом.
Выберите параметр «activity_main.xml (макет)», показанный на рисунке ниже.
Следующие работали для меня:
-> отключить плагин поддержки Android
-> вам будет предложено перезапустить
-> после перезапуска повторно включите плагин и другие плагины зависимостей, которые могли быть отключены в процессе
-> вам будет предложено перезапустить еще раз. Надеюсь, когда андроид-студия перезапустит второй раз, когда предварительный просмотр должен отобразиться.
Получилась та же проблема после импорта моего проекта Eclipse ADT в Android Studio. Text и Desing, где отсутствует.
Найденные окна журнала событий читают «Обнаруженные рамки: инфраструктура Android обнаружена в проекте« Настроить »,
Я нажимаю на предоставленную гиперссылку, и все исправлено, вкладки «Текст» и «Желание» стали видимыми и функциональными
Перейдите в файл -> Структура проекта -> модули -> нажмите кнопку «зеленый плюс», чтобы добавить модуль.
Выберите новый модуль -> выберите «Прикладной модуль» в Android-опции -> укажите имя модуля -> next -> next -> finish
Выберите проект, который будет включен в модуль -> нажмите apply -> okay
Теперь вы сможете увидеть полную структуру проекта; Затем откройте окно проекта формы модуля (левая панель), выберите res, затем выберите макет -> имя макета (.xml).
Теперь вы сможете увидеть дизайн и просмотр текста как …
Ребята все очень просто … 1. Просто введите в поиск «Предварительный просмотр», и он покажет вам единственный результат. Просто нажмите на него, и предварительный просмотр появится снова 🙂 2. Потяните правую сторону и появится окно. Это своего рода изменение размера.
Перейдите в Файл-> Недействительный кэш / Перезапуск.
Это решит проблему.
Как сказал Этьен, убедитесь, что XML-файл, на который вы смотрите, находится в src/main/res/layout
Я была такая же проблема. Если вы находитесь в файле макета в каталоге build , вы не увидите предварительный просмотр, и вы не сможете включить его в качестве опции. Я хочу, чтобы у Google было небольшое предупреждение.
Если вы хотите увидеть предварительный просмотр в реальном времени , в правой части экрана вы должны нажать кнопку « Предварительный просмотр», чтобы показать / скрыть предварительный просмотр в реальном времени.
Если вы хотите использовать режим редактора WYSISYG, в нижней части редактора есть вкладка, которая переключается между режимом XML и режимом WYSISYG .
Это работает так же, как в IntelliJ и Android Studio.
У меня была такая же проблема и разрешена путем редактирования t-файла в макете src> main> res>. Вы можете выбрать режим тестирования и дизайна в нижней части редактора.
Довольно просто, если мы знаем, где искать . Потратьте несколько часов на это!
Файл >> настройка >> Компилятор >> JavaCompiler В версии проекта bytecode (оставьте поле пустым для jdk default): «выберите свой jdk.
У меня была эта проблема пару часов назад, когда я экспортировал свои проекты из Eclipse в Android Studio. К сожалению, верхние ответы здесь не сработали для меня.
Во всяком случае, создание нового проекта вместо того, чтобы открыть старый, сделало для меня трюк, как то, что Томас Калякос упомянул в своем комментарии здесь
Я должен был возиться с проектом … и в какой-то момент это сработало. Однако я не знаю, как это сделать. Я предполагаю, что создание нового проекта и добавление исходного кода будут работать каждый раз. Извините за то, что я не очень ясен, но, честно говоря, я даже удивился, что это сработало. – Thomas Kaliakos Oct 15 ’13 в 4:08
В случае, если вам нужен режим стыковки (он все еще отображается при редактировании xml-файла), и вы, по ошибке, нажали и не отмечали пристыкованный режим. Чтобы вернуть его, вы сосредоточитесь на предварительном просмотре и нажмите « Window > Active Tool Window > Docked Mode .
Если вы видите сообщение внизу, что-то типа «Android Framework обнаружен. Нажмите, чтобы настроить», DO IT.
После этого появились мои нижние вкладки «Текст и дизайн».
В первую очередь после создания нового приложения
Перейти к java-> MainActivity
И откройте для него новую вкладку
В java-коде нажмите на индексные номера, где вы можете увидеть логотип кода
Как красный обведен в картине
Щелкните левой кнопкой мыши по нему, и вы увидите две опции, как показано на рисунке ниже.
Нажмите на первый вариант, чтобы вы могли просмотреть свое приложение в студии Android.
Источник