Как изменить цвет фона в android studio в приложении
Продолжаем изучать основы разработки приложений с использованием языка Kotlin.
Это уроки по основам разработки, и мы еще не дошли до собственно программирования на языке Kotlin, поскольку разработка приложений – это не только программирование. В этом уроке мы рассмотрим ресурсы приложения, а также создадим макеты для экранов приложения. Писать программные конструкции на языке Kotlin мы начнем в следующем уроке.
Как правило, каждый экран в вашем приложении для Android связан с одним классом Java или Kotlin, известным как Activity. Этот термин можно перевести как активность или деятельность, но мы будем использовать термин активити, без перевода. Единственный экран с отображенным «Hello World» создается с помощью активити MainActivity.kt. Это активити было создано средой разработки, когда вы создали свой новый проект. Каждое видимое активити в приложении для Android имеет макет, который определяет пользовательский интерфейс для активити. Android Studio имеет редактор макетов, в котором вы можете создавать и определять макеты.
Макеты описаны в XML. Редактор макета позволяет вам определять и изменять макет либо путем кодирования XML, либо с помощью интерактивного визуального редактора. Вы можете переключаться между редактированием макета в XML и в редакторе визуального дизайна и создавать макеты любым способом.
1 . Редактор макета в Android Studio
Каждый элемент в макете представляет собой view, или представление. В этой задаче изучим интерфейс редактора макетов в Android Studio и разберемся, как изменять значения свойств для view.
Что вы узнаете
- Как использовать редактор макетов.
- Как установить значения свойств.
- Как добавить строковые ресурсы.
- Как добавить цветовые ресурсы.
Откройте редактор макета
Изучите и измените размер дерева компонентов
- Посмотрите на дерево компонентов в левом нижнем углу вкладки «Дизайн».
На этой панели отображается иерархия представлений view в вашем макете. - Отрегулируйте стороны панелей так, чтобы вы могли видеть все в Дереве компонентов.
- Щелкните значок «Закрыть панель» в правом верхнем углу дерева компонентов.Панель Component Tree закрывается.
- Верните панель Component Tree, щелкнув по вертикальной метке «Дерево компонентов» слева.Теперь, когда вы знаете, как изменять размер, закрывать и открывать панель Component Tree, пришло время изучить иерархии представлений view.
Исследуйте иерархии представлений view
Далее в этом уроке мы рассмотрим работу с ConstraintLayout более подробно.
- Обратите внимание, что ConstraintLayout содержит TextView.
- Просмотрите XML-код для макета, щелкнув вкладку « Текст » в нижней части вкладки «Дизайн».
- В коде XML обратите внимание, что корневой элемент <android.support.constraint.ConstraintLayout>. Корневой элемент содержит один <TextView> элемент.
В приложении Andro >res/values и также, как и ресурсы строк, заключены в тег . Так, по умолчанию при создании самого простого проекта в папку res/values добавляется файл colors.xml :
Для задания цветовых ресурсов можно использовать следующие форматы:
Изменим файл colors.xml, добавив еще один цвет:
Применим цвета в файле activity_main.xml :
С помощью атрибута android:textColor устанавливается цвет текста в TextView, а атрибут android:background устанавливает фон TextView. В качестве значения они используют цвет, например, в том же шестнадцатеричном формате. Для получения самого цвета после "@color/" указывается имя ресурса.
Также можно использовать цветовые ресурсы в коде MainActivity:
Для закрепления навыков создадим приложение чуть посложнее предыдущего, а также познакомимся с другими приёмами программирования.
В качестве примера напишем программу под условным названием «Светофор». Интерфейс программы будет выглядеть следующим образом. На красном экране расположены три кнопки и одна текстовая надпись. При нажатии кнопок фон программы будет меняться на соответствующий цвет, который закреплён за определённой кнопкой. Я попробую вам показать решение задачи с разных сторон, чтобы вы почувствовали себя увереннее.
Первые шаги вполне очевидны. Создаём новый проект на основе "Hello, World" и перетаскиваем с панели инструментов три кнопки. Когда будете размещать кнопку, попробуйте потаскать её по разным позициям внутри экрана активности. Вы будете замечать различные всплывающие линии, подсказывающие о стандартных отступах от края или о центральной оси по вертикали и горизонтали. Это удобно, когда вы точно знаете, где нужно разместить один компонент.
В нашем случае мы поступим иначе. Сначала просто перетащим три кнопки на экран, не думая о позиционировании. Далее в окне Component Tree выделяем три кнопки, удерживая клавишу Shift, вызываем контекстное меню и выбираем команды Center Horizontally и потом Center Vertically. Кнопки равномерно распределятся по экрану.
В окне Component Tree выделите строку button. У вас должно появиться окно свойств Properties. Давайте избавимся от стандартных идентификаторов, а будем сразу приучаться давать осмысленные имена. Например, для первой кнопки присвоим свойству id значение buttonRed вместо стандартного @+id/button
Для второй кнопки присвоим значение buttonYellow.
Аналогично настраиваем третью кнопку buttonGreen.
Строковые ресурсы
Теперь нам нужно заменить текст на кнопках на слова Красный, Жёлтый и Зелёный. На прошлом уроке мы просто присвоили свойству Text нужную строку. Но на самом деле это неправильный подход и даже среда разработки выводит предупреждающие значки у кнопок, если вы переключитесь в режим Text. По правилам, строки нужно хранить в строковых ресурсах. Подобный подход даёт разработчику множество преимуществ, в частности, быструю локализацию приложения. Считайте это стандартом, которого нужно придерживаться.
Процесс создания строковых ресурсов очень прост. Переключитесь обратно в режим Design и выберите кнопку buttonRed. В окне свойств найдите свойство text. Рядом находится кнопка с многоточием. Щёлкните на кнопке. У вас откроется диалоговое окно Resources.
Нажмите на выпадающий список Add new resource для создания нового строкового ресурса и выберите New String Value.
В новом окне New String Value Resource в первом поле Resource Name введите название ресурса, например, red, а во втором поле Resource Value введите текст для кнопки (напр. Красный). Остальные поля не трогаем. Аналогичным образом поступите с другими двумя кнопками (Жёлтый и Зёленый).
Программно можно добиться такого же результата, отредактировав файл strings.xml, который находится в папке res/values вашего проекта. Сейчас он может выглядеть так.
Мы совсем забыли про элемент TextView. Исправим упущение. Разместим компонент под кнопками и снова сделаем выравнивание.
Пусть на нём выводится текст, извещающий о текущем цвете фона приложения. Так как в ресурсах у нас уже есть слова Красный, Жёлтый и Зелёный, изначально предназначенные для кнопок, то мы не будем создавать новые строковые ресурсы, а воспользуемся готовыми наработками. По умолчанию у нас используется красный цвет. В окне свойств выбираем свойство text для TextView и нажимаем кнопку с многоточием для вызова знакомого диалогового окна. На этот раз мы не будем щёлкать на кнопке New Resource, а сразу выберем строку red, которая, как мы помним, содержит текст Красный и щёлкнем кнопку OK (можно сделать сразу двойной щелчок на строке).
Заодно расскажу о другой настройке под ней с изображением гаечного ключа и таким же названием text. Представьте себе, что в реальной программе изначально у TextView нет никакого текста, он будет сформирован позже программно. Но чтобы разработчик видел, как будет выглядеть дизайн экрана, ему нужно видеть текст на этапе проектирования. Для этих целей и предназначена вторая настройки для текста. Подобное вы можете увидеть и у других свойства компонента.
С текстом разобрались. Но где остальные настройки? В окне свойств Properties нажмите на ссылку View all properties. Тут увидите все доступные атрибуты для компонента. Если вы не помните точное название, то воспользуйтесь поиском. Я помню, что для размера шрифта используется что-то со словом size. Вспомнил, это textSize.
Выбираем нужное значение из выпадающего списка. Студия предлагает варианты, которые рекомендованы по правилам Material Design. Если вы хотите установить своё значение, то переключитесь в режим Text и вручную поменяйте значение. Если этого не сделать, а пытаться отредактировать значение в режиме Design, то студия не будет реагировать.
Рекомендую постоянно переключаться в режим Text и смотреть, что происходит в коде. Это позволит вам увереннее разбираться в коде и читать чужой код. Как правило, новички предпочитают работать через визуальные инструменты, а программисты с опытом самостоятельно пишут практически весь код. Нужно найти разумный баланс между двумя подходами. Всё придёт со временем.
Со строками вроде разобрались. Давайте теперь в ресурсах зададим цвета для фона программы. Ресурсы для цветов принято хранить в отдельном файле res/values/colors.xml, хотя технически никто не запрещает хранить их в том же файле strings.xml.
Откроем указанный файл и добавим ресурс жёлтого цвета между тегами resources:
Слева появится жёлтый квадрат, по нему легко видеть цвет заданного ресурса.
По такому же принципу добавьте зелёный цвет.
Самостоятельно добавьте ресурс для красного цвета под именем redColor.
Если вам знаком такой формат цвета, то трудностей добавление новых цветов подобным способом вам не доставит. Если нужно выбрать более сложный цвет, то проще воспользоваться мастером, как мы это делали в уроке "Hello Kitty", когда выбирали розовый цвет, а затем полученный цвет скопировать в ресурсы.
Определив в ресурсах все необходимые цвета, можно сразу присвоить красный цвет для контейнера ConstraintLayout. В окне свойств находим для данного элемента свойство background (чтобы увидеть все свойства компонента, нажмите ссылку View all properties). Снова нажимаем кнопку с тремя точками, чтобы открыть диалоговое окно. В окне выбираем раздел Color и ищем свой ресурс redColor.
Если посмотреть в текстовом режиме, то увидите строчку andro для тега ConstraintLayout.
Так как мы будем менять фон у ConstraintLayout, то присвоим ему идентификатор.
Общий каркас приложения завершен. У нас есть три кнопки с соответствующими текстами, текстовая надпись со словом Красный, и красный фон, используемый в контейнере ConstraintLayout. Пора приступать к программной логике программы. А пока можно запустить приложение, чтобы убедиться, что мы не сделали ошибок в разметке.
Код для программы
Объявим переменные в классе и получим к ним доступ в методе onCreate():
Напоминаю, что код нужно писать вручную, а не копировать с сайта. Тогда многие вопросы отпадут и вам не придётся бежать на форум с криками, что ничего не работает.
Кстати, этот код вызвал трудности у новичков. Меня завалили письмами и устроили вой на форуме. Раньше в студии по умолчанию использовался компонент RelativeLayout и пример был написан под него. Новички размещали кнопки в ConstraintLayout, а в код вставляли строчки:
Пишем код для щелчка кнопки с надписью "Красный":
Мы обращаемся к созданным ресурсам через специальный класс R и через точку указываем тип ресурсов, а затем имя ресурса.
Для кнопки "Зелёный" напишите код самостоятельно, добавив метод onGreenButtonClick().
Для кнопки "Жёлтый" напишем код в традиционной манере через слушателя OnClickListener. В методе onCreate() добавляем:
Раньше для изменения кода использовался код:
В Android 6 (API 23) метод getColor(int id) объявили устаревшим и студия теперь подчёркивает данный метод. Можно заменить на один из двух вариантов:
Первый вариант подойдёт, если вы не поддерживаете старые устройства, а сразу пишете приложение для телефонов с API 23. Второй способ более универсальный. Его я и использовал.
Полный текст кода будет выглядеть следующим образом:
В качестве домашнего задания упростите код для трёх кнопок, создав для них общий метод onClick() (почитайте статью про кнопки).
Приведённая ниже информация немного устарела. В Android 5.0 используется другой стиль оформления заголовка программы и значка там теперь нет (хотя его можно туда поместить). Но значки всё равно нужны для отображения вашей программы на домашнем экране или в лаунчерах.
Если вы не хотите менять существующие стандартные значки, а хотите использовать значки под другим именем, то в этом случае подготовьте все необходимые размеры, разместите их во всех папках mipmap- под своим именем, а затем в манифесте замените строчку у атрибута android:icon:
В состав студии входит набор предопределённых значков и генератор собственных значков. Щёлкните правой кнопкой на папке drawable или mipmap и выберите в меню New | Image Asset.
Откроется диалоговое окно, где вы можете указать в качестве источника файл на компьютере, вариант из клипарта или набор символов. Также вы можете задать форму значка, цвет фона и прочие параметры. Уверен, что вы разберётесь самостоятельно.
Кроме значков для различных разрешений, генератор создаст дополнительный файл с суффиксом -web, который будет скопирован в папку main. Этот файл используется для Google Play, когда будете размещать приложение в магазине приложений и давать описание к нему.
Andro . Предполагается, что изображение earth хранится в директории проекта res/drawable. На следующем скриншоте представлено изображение земли earth.jpg, которое будет использовано в описанном ниже примере в качестве фонового изображения разметки интерфейса Layout.
В чем особенность данного фонового изображения? Прямоугольный размер картинки включает расположенное не по центру изображение земли, которое при смене ориентации (orientation) будет «сплющиваться». Все правильные фигуры изображения будут изменять геометрические размеры, поскольку android будет непропорционально растягивать или сжимать фоновое изображения. На следующем скриншоте представлено данное фоновое изображение при повороте устройства android в положение portrait.
В этой статье рассмотрим вопросы размещения и адаптации фонового изображения в разметке интерфейса в зависимости от ориентации устройства. Нам необходимо будет научиться перехватывать обработку события при изменении положения устройства, и устанавливать соответствующее его ориентации фоновое изображение разметки.
Рассмотрим пример использования фонового изображения в разметке интерфейса. Нам необходимо :
- определить фоновое изображение в разметке интерфейса;
- подключиться к событию изменения положения/ориентации устройства;
- определить фоновое изображение согласно положению/ориентации устройства.
Создайте новый модуль Module приложения и разместите два изображения (earth_portrait.jpg, earth_landscape.jpg) в директории проекта res/drawable. Правильнее было бы, конечно, создать несколько изображений под разные разрешения, о чем сказано в описании ImageView. Но, для решения текущей задачи обойдемся «малой кровью», т.е. двумя изображениями. Изображения можно скачать в конце статьи.
Разметка интерфейса
В файле описания интерфейса приложения res/layout/activity.xml определяем два атрибута : background и orientation. В атрибуте android:background определяем ресурсный файл одного из изображениий. Атрибут android:orientation добавляем в описание разметки LinearLayout, чтобы среда разработки Android Studio не «ругалась».
Изменение положения устройства
Для того, чтобы подключиться к событию изменения положения устройства необходимо переписать метод активности onConfigurationChanged и соответствующим образом определить атрибут configChanges в файле манифеста проекта, чтобы система вызывала этот метод.
Метод onConfigurationChanged
Метод активности onConfigurationChanged в качестве параметра получает значение конфигурации устройства, которое передается родительскому (super) методу. Новое положение устройства сохраняем в переменной orientation и после этого вызываем метод определения фонового изображения setBackgroundImage.
Для чего нам необходима переменная orientation? Давайте представим ситуацию, что в приложении несколько активностей. В одной из активностей положение устройства изменяется, и после этого открывается данная активность. Система вызовет представленный (переопределенный в листинге) метод onResume, в котором будет определяться соответствующее фоновое изображение вызовом метода setBackgroundImage.
Итак, в листинге были переопределены два метода активности : onConfigurationChanged и onResume. Но, чтобы система вызвала метод onConfigurationChanged, необходимо настроить манифест приложения.
Манифест AndroidManifest.xml
Дополнительную информацию по настройкам манифеста приложений с несколькими активностями, а также для взаимодействия разных приложений между собой можно получить на странице описания намерений Intent.
Активность приложения MainActivity
В активности приложения только определяется первоначальное значение переменной orientation. В листинг не включены представленные выше методы.
После старта приложения можно изменять положение устройства с portrait на landscape и обратно. Переопределенные в активности методы будут корректно устанавливать соответствующие фоновые изображения.
Каждому Android-разработчику так или иначе приходилось работать со стилями. Кто-то чувствует себя с ними уверенно, у кого-то есть только поверхностные знания, которые зачастую не позволяют самостоятельно решить поставленную задачу.
В преддверии выхода темной темы было решено освежить в памяти всю информацию, касающуюся тем и стилей в Android-приложениях.
О чем пойдет речь:
- Рассмотрим основные понятия тем и стилей в Android-приложениях, посмотрим какие возможности они нам предоставляют;
- Создадим простейшую тему с использованием Material Components и поиграемся с переопределением стилей;
- Разберемся, как работает темная тема;
- Сформулируем рекомендации для работы со стилями.
Начнем с основ
По своей структуре темы и стили имеют общее строение:
Для создания используется тег style . У каждого cтиля есть имя и он хранит в себе параметры key-value .
Все достаточно просто. Но в чем же разница между темой и стилем?
Единственное отличие заключается в том, как мы их используем.
Тема — это набор параметров, которые применяются ко всему приложению, Activity или View-компоненту. Она содержит базовые цвета приложения, стили для отрисовки всех компонентов приложения и различные настройки.
В теме переопределены основные цвета приложения ( colorPrimary , colorSecondary ), стиль для текста ( textAppearanceHeadline1 ) и некоторых стандартных компонентов приложения, а также параметр для прозрачного статус-бара.
Для того чтобы стиль стал настоящей темой, необходимо отнаследоваться (о наследовании мы поговорим чуть позже) от дефолтной реализации темы.
Стиль
Стиль — это набор параметров для стилизации одного View-компонента.
Атрибут
Атрибутом принято называть ключ стиля или темы. Это маленькие кирпичики из которых все строится:
Все эти ключи являются стандартными атрибутами.
Мы можем создавать свои атрибуты:
Атрибут myFavoriteColor будет указывать на цвет или ссылку на ресурс цвета.
В формате мы можем указать вполне стандартные значения:
По своей природе атрибут является интерфейсом. Его необходимо реализовать в теме:
Теперь мы можем на него ссылаться. Общая структура обращения выглядит так:
Ну и, наконец, давайте поменяем, например, цвет текста у поля:
Благодаря атрибутам мы можем добавлять какие-угодно абстракции, которые будут изменяться внутри темы.
Наследование тем и стилей
Как и в ООП, мы можем перенимать функционал существующей реализации. Сделать это можно двумя способами:
При явном наследовании мы указываем родителя с помощью ключевого слова parent :
При неявном наследовании мы используем dot-notation для указания родителя:
Никакой разницы в работе этих подходов нет.
Очень часто мы можем встретить подобные стили:
Может показаться, что стиль создан путем двойного наследования. На самом деле это не так. Множественное наследование запрещено. В таком определении явное наследование всегда выигрывает.
То есть будет создан стиль с именем Widget.MyApp.Snackbar , который является наследником Widget.MaterialComponents.Snackbar .
ThemeOverlay
ThemeOverlay — это специальные «легковесные» темы, которые позволяют переопределить атрибуты основной темы для View-компонента.
За примером далеко ходить не будем, а возьмем кейс из нашего приложения. Дизайнеры решили, что нам нужно сделать стандартное поле для ввода логина, которое будет иметь отличный от основного стиля цвет.
С основной темой поле ввода выглядит так:
Выглядит отлично, но дизайнеры настаивают на том, чтобы поле было в коричневом стиле.
Окей, как мы можем решить такую задачу?
Да, мы можем переопределить стиль и вручную поменять основные цвета вьюшки, но для этого нужно будет писать много кода, да и есть шанс, что мы про что-нибудь забудем.
Написать свою вьюшку по гайдлайнам и с кастомными параметрами?
Хороший вариант, так мы сможем удовлетворить любые хотелки дизайнеров и заодно прокачать скилл, но все это трудозатратно и может привести к нежелательным багам.
Переопределить основной цвет в теме?
Мы выяснили, что для нужного нам вида достаточно поменять colorPrimary в теме. Рабочий вариант, но так мы затронем внешний вид остальных компонентов, а нам это не нужно.
Правильное решение — это использовать ThemeOverlay.
Создаем ThemeOverlay и переопределяем основной цвет темы:
Далее указываем его с помощью специального тега android:theme в наш TextInputLayout :
Все работает так, как нам и нужно.
Конечно же возникает вопрос — как это работает под капотом?
Эту магию позволяет провернуть ContextThemeWrapper . При создании View в LayoutInflater будет создан контекст, где за основу будет взята текущая тема и в ней будут переопределены параметры, которые мы указали в нашей Overlay теме.
Аналогичным образом мы можем самостоятельно переопределить любой параметр темы в приложении.
Последовательность применения тем и стилей ко View-компоненту
Главный приоритет имеет файл разметки. Если в нем определен параметр, то далее все аналогичные параметры будут игнорироваться.
Следующий приоритет имеет стиль View:
Далее используются предопределенные стили для компонента:
Если параметры не были найдены, то используются атрибуты темы:
В общем-то это все, что нужно знать для того чтобы начать работу с темами. Теперь кратко посмотрим на обновленную дизайн-библиотеку Material Components.
Да прибудет с нами Material Components
Material Сomponents была представлена на Google I/O 2018 и является заменой Design Support Library.
Библиотека дает нам возможность использовать обновленные компоненты из Material Design 2.0. Кроме того, в ней появилось множество интересных настроек по кастомизации. Все это позволяет писать яркие и уникальные приложения.
Вот некоторые примеры приложений в новом стиле: Owl, Reply, Crane.
Перейдем к практике
Для создания темы нужно отнаследоваться от базовой темы:
Все они очень похожи на AppCompat темы, но имеют дополнительные атрибуты и настройки.
Подробнее с новыми атрибутами можно познакомиться на material.io.
Если по каким-то причинам вы сейчас не можете переключиться на новую тему, то вам подойдут Bridge темы. Они наследуются от AppCompat тем и имеют все новые атрибуты Material Components. Нужно всего лишь добавить постфикс Bridge и использовать все возможности без опасений:
А вот и наша тема:
Имена основных цветов (brand-цветов) претерпели изменения:
Дополнительную информацию по цветам можно найти на material.io.
Я уже упоминал, что тема содержит стандартные стили для каждого View-компонента. Например, для Snackbar стиль будет называться snackbarStyle , для checkbox — checkboxStyle и далее все по аналогии. Пример расставит все на свои места:
Создадим свой стиль и применим его к теме:
Важно понимать, что когда вы переопределяете стиль в теме, он применится ко всем View этого типа в приложении (Activity).
Если же вы хотите применить стиль только к одной конкретной View, то нужно использовать тег style в файле с разметкой:
Одно из нововведений, которое меня действительно впечатлило — это ShapeAppearance. Оно позволяет изменять форму компонентов прямо в теме!
Каждый View-компонент относится к определенной группе:
shapeAppearanceSmallComponent
shapeAppearanceMediumComponent
shapeAppearanceLargeComponent
Как мы можем понять из названия, в группах вьюшки разных размеров.
Проверим на практике:
Мы создали Widget.MyApp.SmallShapeAppearance для "маленьких" компонентов. Закруглили верхний левый угол на 20dp и правый нижний угол срезали на 15dp .
Получили такой результат:
Выглядит интересно. Будет ли это работать в реальной жизни? Время покажет.
Как и для стилей, мы можем применить ShapeAppearance только для одного View-компонента.
Что там по темной теме?
Совсем скоро состоится релиз Android Q, а вместе с ним к нам придет и официальная темная тема.
Пожалуй, одна из самых интересных и эффектных возможностей новой версии Android — это автоматическое применение темной темы для всего приложения одной строчкой кода.
Звучит здорово, давайте пробовать. Предлагаю взять всеми любимый гитлаб клиент от terrakok.
Разрешаем перекрашивать приложение (по умолчанию запрещено):
Атрибут android:forceDarkAllowed доступен с API 29 (Android Q).
Запускаем, смотрим что получилось:
Согласитесь, что для одной строчки кода выглядит очень круто.
Конечно, есть проблемы — BottomNavigationBar сливается с фоном, лоадер остался белым, выделение кода страдает и, вроде бы, все, по крайне мере мне больше ничего серьезного в глаза не бросилось.
Уверен, что потратив не так много времени, можно решить основные проблемы. Например, отключив автоматический темный режим для отдельных вьюшек (да, так тоже можно — android:forceDarkAllowed доступен для View в файле-разметке).
Следует помнить, что данный режим доступен только для светлых тем, если вы используете темную, то принудительная темная тема работать не будет.
Рекомендации по работе можно почитать в документации и на material.io.
А если мы хотим все делать самостоятельно?
Как бы не было просто использовать принудительную темную тему, этот режим лишен гибкости. Фактически, все работает по заранее определенным правилам, которые могут не устраивать нас и, что более важно, заказчика. Думаю, что такое решение можно рассматривать как временное, до тех пор пока мы не сделаем свою реализацию темной темы.
В API 8 (Froyo) был добавлен квалификатор -night , который и по сей день используется для применения темной темы. Он позволяет автоматически применять нужную тему в зависимости от времени суток.
В темах DayNight уже используется такая реализация, нам достаточно отнаследоваться от них.
Давайте попробуем написать свою:
В обычном ресурсе для темы ( values/themes.xml ) мы наследуемся от светлой темы, в "ночном" ( values-night/themes.xml ) ресурсе наследуемся от темной темы.
На этом все. Мы получили библиотечную реализацию темной темы. Теперь нам следует поддерживать ресурсы для двух тем.
Чтобы переключаться между темами во время работы приложения можно воспользоваться AppCompatDelegate.setDefaultNightMode , который принимает следующие параметры:
- MODE_NIGHT_NO — Светлая тема;
- MODE_NIGHT_YES — Темная тема;
- MODE_NIGHT_AUTO_BATTERY — Автоматический режим. Включается темная тема, если активен режим энергосбережения;
- MODE_NIGHT_FOLLOW_SYSTEM — Режим на основе системных настроек.
Что нам следует учитывать при работе с темами и стилями?
Как я уже отметил, Google начал официально форсить темную тему. Уверен, что от многих заказчиков начали поступать вопросы — «Сможем ли мы добавить темную тему?». Хорошо, если вы с самого начала все делаете правильно и вам не составит труда поменять светлые цвета на темные, получив при этом полностью перекрашенное приложение.
К сожалению, так бывает далеко не всегда. Бывают старые приложения, которые требуют значительных усилий для того, чтобы внести необходимые изменения.
Давайте вместе попытаемся сформулировать рекомендации для работы со стилями:
1. Палитра цветов
Думаю, что каждый разработчик сталкивался с ситуацией когда в новом макете появляется какой-то непонятный цвет, который еще не определен в палитре приложения. Что делать в таком случае?
Правильный ответ — поговорить с дизайнером и попытаться выработать палитру цветов. Сейчас есть множество программ (Zeplin, Sketch и др.), которые позволяют вынести основные цвета и потом переиспользовать их.
Чем раньше вы этим займетесь, тем меньше у вас будет головной боли в дальнейшем.
2. Называть цвета своими именами
В каждом приложении найдется цвет, который имеет множество вариантов яркости. Можно для них начать выдумывать имена:
Согласитесь, выглядит не очень. Сразу возникает вопрос — какой цвет светлее tiny или light ? А если у нас будет десяток вариантов?
Лучше всего придерживаться концепции Google и добавить в имена цветов соответствующую яркость (Google называет это вариантом цвета — colorVariant ):
При таком подходе мы сможем иметь сколько угодно вариантов яркости одного цвета и нам не придется придумывать специфичные имена, а это действительно трудно.
3. Абстрагироваться от конкретного цвета, если он меняется в разных темах
Так как мы пишем приложение в котором будет как минимум две темы, то мы не можем позволить себе ссылаться на конкретный цвет, если он реализуется в темах по-разному.
Давайте рассмотрим пример:
Мы видим, что в светлой теме, например, тулбар окрашен в фиолетовый, а в темной он темно-серый. Как бы нам реализовать такое поведение, используя только возможности тем?
Все достаточно просто — мы создадим атрибут и реализуем его в светлой и темной темах соответствующим цветом, как это описывалось ранее.
Google рекомендует связывать имена атрибутов с семантикой использования.
4. Не бояться создавать ресурсные файлы
Когда в файле styles.xml набирается много различных стилей, тем и атрибутов, то его становится сложно поддерживать.
Лучше всего разнести все по группам в отдельные файлы:
Такое простое правило позволит избежать God-файлов и, следовательно, будет проще поддерживать стили.
5. Переиспользовать по максимуму
Как мы поступим, если захотим переопределить атрибут, который доступен только с определенной версии API?
Мы можем создать две отдельные темы:
Нам теперь на каждую версию API делать тему со всеми параметрами? Нет, конечно! Мы сделаем базовую тему, где будут определены базовые атрибуты, доступные для всех версий API и отнаследуемся от нее в нужной версии API:
По такому принципу построены все темы в стандартной библиотеке.
6. Использовать векторные ресурсы и tint
Думаю, не стоит говорить почему векторные ресурсы — это хорошо. Все и так знают (на всякий случай ссылка на документацию). Ну а tinting поможет нам окрасить их в цвета темы.
Посмотреть что такое tinting и как с ним работать можно в этом примере.
7. ?android:attr/… vs ?attr/.
При обращении к ресурсам у нас есть возможность использовать как системные атрибуты, так и атрибуты из библиотеки Material Components. Важно понимать, что некоторые атрибуты существуют только с определенной версии API. Как мы все хорошо знаем, обращение к несуществующему ресурсу ведет к крэшу (lint, конечно, нам подскажет если что-то не так, но не стоит всегда полагаться на него)
В первом случае мы обращаемся к системному ресурсу, так как указали android . Во втором случае к атрибуту из библиотеки, где реализована обратная совместимость.
Лучше всегда использовать второй вариант.
8. Всегда указывать родителя для стиля
В родительском стиле могут быть параметры, без которых компонент будет неверно отрисовываться, поэтому следует всегда указывать родителя.
9. Тема, стиль или… ?
При созданий собственных тем и стилей будет здорово, если вы укажите префикс, говорящий о том что это за стиль и для чего он определен. Такое именование позволит очень просто структурировать и расширять стили.
10. Использовать TextAppearance
Хорошим тоном будет расширить основные стили для текста и везде их использовать.
Много полезной информации можно найти на сайте Material Design: Typography, Typography Theming.
Заключение
В заключение хочется сказать, что стилизация приложения — это обязанность не только разработчиков, но и дизайнеров. Только благодаря тесному взаимодействию мы сможем получить по-настоящему хороший и красивый продукт. Дизайнеры должны иметь представления о платформе и возможностях Material Components. Ведь именно на их плечи ложится ответственность по поддержке визуальной составляющей приложения. Дизайнерам доступен специальный плагин для Sketch — Material Theme Editor. В нем очень просто выбирать цвета для приложения и строить экраны на основе стандартных компонентов. Если ваши дизайнеры еще не знают о нем, то обязательно расскажите им.
Начать изучать Material Components можно с репозитория на GitHub — Modular and customizable Material Design UI components for Android. В нем собрано очень много информации по стандартным стилям и их возможностям. Кроме того, там есть приложение — sample, чтобы все сразу попробовать на практике.
Писать все на одно лицо приложение не очень то и хочется, хочется сделать уникально красивое и удобное, так чтобы с одного вида хотелось его использовать. Именно об этом и пойдет речь в данном уроке, а именно о создании своего стиля для приложения.
Шаг 1: Создание нового проекта
Создаем новое приложение в Intellij IDEA -> Android Module 4.3
Шаг 2: Меняем темную тему на светлую
Теперь давайте разберемся, что такое Темы.
Как же это сделать? Первое что можно сделать это поменять к примеру темную тему на светлую. Сделать это можно добавив следующий атрибут в AndroidManifest, изначально он выглядит так:
По умолчанию у нас стоит темная тема, мы сейчас поставим светлую, для это добавим в AndroidManifest следующую строку:
В строке 10 мы говорим, что MainActivity будет иметь светлое оформление, вот такое:
И теперь если добавить кнопку то выглядеть она будет так:
Шаг 3: Создаем новое Activity
Теперь создадим новый layout:
Выглядеть новый layout будет так:
Теперь создадим новое Activity LastActivity:
И в AndroidManifest незабываем добавлять новые activity:
Шаг 4: Делаем переход на новое Activity
Теперь на добавленную кнопку на main.xml добавим обработчик на клик:
и укажем кнопки чтобы при клике выполнялся goToLastActivity() метод:
Теперь при клике на кнопку New Theme будет открываться новое Activity.
Шаг 5: Делаем с Activity Dialog
Давайте изменим новому Activity lastactivity.xml вид диалогового окна.
Для этого зайдите в AndroidManifest и в для нового Activity, а именно LastActivity установите следующую тему:
После этого мы получим следующий вид данного activity:
Шаг 6: Меняем иконку приложения
Для этого копируем новую иконку в папки drawable-hdpi, drawable-ldpi, drawable-mdpi, drawable-xhdpi для того чтобы эта иконка отображалась на любом размере дисплея.
Дальше в AndroidManifest нужно изменить эту строку, где вы должны указать имя вашей картинки:
Читайте также: