Стили и темы

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

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

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

Тема — это набор атрибутов, которые применяются ко всей иерархии приложения, действия или представления, а не только к отдельному представлению. Когда вы применяете тему, каждое представление в приложении или действии применяет все поддерживаемые атрибуты темы. Темы также могут применять стили к элементам, не являющимся представлением, например к строке состояния и фону окна.

Стили и темы объявляются в файле ресурсов стиля в res/values/ , обычно называемом styles.xml .

Рисунок 1. Две темы, примененные к одному и тому же действию: Theme.AppCompat (слева) и Theme.AppCompat.Light (справа).

Темы против стилей

Темы и стили имеют много общего, но используются для разных целей. Темы и стили имеют одинаковую базовую структуру — пару ключ-значение, которая сопоставляет атрибуты с ресурсами .

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

Тема определяет коллекцию именованных ресурсов, на которые могут ссылаться стили, макеты, виджеты и т. д. Темы присваивают ресурсам Android семантические имена, например colorPrimary .

Стили и темы предназначены для совместной работы. Например, у вас может быть стиль, указывающий, что одна часть кнопки — colorPrimary , а другая — colorSecondary . Фактические определения этих цветов представлены в теме. Когда устройство переходит в ночной режим, ваше приложение может переключиться со «светлой» темы на «темную», изменяя значения для всех этих имен ресурсов. Вам не нужно менять стили, поскольку в стилях используются семантические имена, а не конкретные определения цветов.

Дополнительные сведения о том, как темы и стили работают вместе, см. в записи блога «Стилизация Android: темы и стили» .

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

Чтобы создать новый стиль, откройте файл res/values/styles.xml вашего проекта. Для каждого стиля, который вы хотите создать, выполните следующие действия:

  1. Добавьте элемент <style> с именем, которое однозначно идентифицирует стиль.
  2. Добавьте элемент <item> для каждого атрибута стиля, который вы хотите определить. name в каждом элементе указывает атрибут, который вы в противном случае используете в качестве атрибута XML в макете. Значение элемента <item> является значением этого атрибута.

Например, предположим, что вы определяете следующий стиль:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="GreenText" parent="TextAppearance.AppCompat">
        <item name="android:textColor">#00FF00</item>
    </style>
</resources>

Вы можете применить стиль к виду следующим образом:

<TextView
    style="@style/GreenText"
    ... />

Каждый атрибут, указанный в стиле, применяется к этому представлению, если представление его принимает. Представление игнорирует любые атрибуты, которые оно не принимает.

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

Расширьте и настройте стиль

При создании собственных стилей всегда расширяйте существующий стиль из платформы или библиотеки поддержки, чтобы обеспечить совместимость со стилями пользовательского интерфейса платформы. Чтобы расширить стиль, укажите стиль, который вы хотите расширить, с помощью parent атрибута. Затем вы можете переопределить унаследованные атрибуты стиля и добавить новые.

Например, вы можете унаследовать внешний вид текста платформы Android по умолчанию и изменить его следующим образом:

<style name="GreenText" parent="@android:style/TextAppearance">
    <item name="android:textColor">#00FF00</item>
</style>

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

Чтобы наследовать стили из библиотеки или собственного проекта, объявите имя родительского стиля без части @android:style/ показанной в предыдущем примере. Например, следующий пример наследует стили оформления текста из библиотеки поддержки:

<style name="GreenText" parent="TextAppearance.AppCompat">
    <item name="android:textColor">#00FF00</item>
</style>

Вы также можете наследовать стили (за исключением стилей, взятых из платформы), расширив имя стиля точечной нотацией вместо использования parent атрибута. То есть добавьте к имени вашего стиля имя стиля, который вы хотите унаследовать, через точку. Обычно вы делаете это только при расширении собственных стилей, а не стилей из других библиотек. Например, следующий стиль наследует все стили GreenText из предыдущего примера, а затем увеличивает размер текста:

<style name="GreenText.Large">
    <item name="android:textSize">22dp</item>
</style>

Вы можете продолжать наследовать подобные стили столько раз, сколько захотите, добавляя больше имен.

Чтобы узнать, какие атрибуты можно объявить с помощью тега <item> , обратитесь к таблице «Атрибуты XML» в различных справочниках классов. Все представления поддерживают атрибуты XML из базового класса View , и многие представления добавляют свои собственные специальные атрибуты. Например, XML-атрибуты TextView включают атрибут android:inputType , который можно применить к текстовому представлению, получающему входные данные, например к виджету EditText .

Применение стиля в качестве темы

Вы можете создать тему так же, как и стили. Разница в том, как вы его применяете: вместо применения стиля с атрибутом style к представлению вы применяете тему с атрибутом android:theme либо к тегу <application> , либо к тегу <activity> в файле AndroidManifest.xml .

Например, вот как применить «темную» тему Material Design из библиотеки поддержки Android ко всему приложению:

<manifest ... >
    <application android:theme="@style/Theme.AppCompat" ... >
    </application>
</manifest>

А вот как применить «легкую» тему только к одному действию:

<manifest ... >
    <application ... >
        <activity android:theme="@style/Theme.AppCompat.Light" ... >
        </activity>
    </application>
</manifest>

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

Начиная с Android 5.0 (уровень API 21) и библиотеки поддержки Android версии 22.1, вы также можете указать атрибут android:theme для представления в файле макета. Это изменяет тему для этого представления и всех дочерних представлений, что полезно для изменения цветовой палитры темы в определенной части вашего интерфейса.

В предыдущих примерах показано, как применить тему, например Theme.AppCompat , предоставленную библиотекой поддержки Android. Однако обычно вам нужно настроить тему в соответствии с брендом вашего приложения. Лучший способ сделать это — расширить эти стили из библиотеки поддержки и переопределить некоторые атрибуты, как описано в следующем разделе.

Иерархия стилей

Android предоставляет множество способов установки атрибутов в вашем приложении Android. Например, вы можете установить атрибуты непосредственно в макете, применить стиль к представлению, применить тему к макету и даже установить атрибуты программным способом.

Выбирая стиль своего приложения, помните об иерархии стилей Android. В общем, используйте темы и стили как можно чаще, чтобы обеспечить единообразие. Если вы укажете одни и те же атрибуты в нескольких местах, следующий список определит, какие атрибуты будут применены в конечном итоге. Список упорядочен от самого высокого приоритета к самому низкому.

  1. Применение стилей на уровне символов или абзацев с использованием текстовых диапазонов к классам, производным от TextView .
  2. Программное применение атрибутов.
  3. Применение отдельных атрибутов непосредственно к представлению.
  4. Применение стиля к представлению.
  5. Стиль по умолчанию.
  6. Применение темы к коллекции представлений, действию или всему приложению.
  7. Применение определенного стиля, специфичного для представления, например установка TextAppearance для TextView .

Рисунок 2. Стилизация из span переопределяет стиль из textAppearance .

Внешний вид текста

Одним из ограничений стилей является то, что к View можно применить только один стиль. Однако в TextView вы также можете указать атрибут TextAppearance , который действует аналогично стилю, как показано в следующем примере:

<TextView
    ...
    android:textAppearance="@android:style/TextAppearance.Material.Headline"
    android:text="This text is styled via textAppearance!" />

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

TextAppearance поддерживает подмножество атрибутов стиля, предлагаемых TextView . Полный список атрибутов см. в TextAppearance .

Не включены некоторые общие атрибуты TextView : lineHeight[Multiplier|Extra] , lines , breakStrategy и hyphenationFrequency . TextAppearance работает на уровне символов, а не на уровне абзаца, поэтому атрибуты, влияющие на весь макет, не поддерживаются.

Настройте тему по умолчанию

Когда вы создаете проект с помощью Android Studio, к вашему приложению по умолчанию применяется тема Material Design, как определено в файле styles.xml вашего проекта. Этот стиль AppTheme расширяет тему из библиотеки поддержки и включает переопределения атрибутов цвета, которые используются ключевыми элементами пользовательского интерфейса, такими как панель приложения и кнопка плавающего действия , если они используются. Таким образом, вы можете быстро настроить цветовой дизайн вашего приложения, обновив предоставленные цвета.

Например, ваш styles.xml выглядит примерно так:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Значения стиля на самом деле являются ссылками на другие ресурсы цвета , определенные в файле res/values/colors.xml проекта. Это файл, который вы редактируете, чтобы изменить цвета. Ознакомьтесь с обзором цветов Material Design , чтобы улучшить взаимодействие с пользователем с помощью динамического цвета и дополнительных настраиваемых цветов.

Как только вы узнаете свои цвета, обновите значения в res/values/colors.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--   Color for the app bar and other primary UI elements. -->
    <color name="colorPrimary">#3F51B5</color>

    <!--   A darker variant of the primary color, used for
           the status bar (on Android 5.0+) and contextual app bars. -->
    <color name="colorPrimaryDark">#303F9F</color>

    <!--   a secondary color for controls like checkboxes and text fields. -->
    <color name="colorAccent">#FF4081</color>
</resources>

Затем вы можете переопределить любые другие стили, которые захотите. Например, вы можете изменить цвет фона активности следующим образом:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:windowBackground">@color/activityBackground</item>
</style>

Список атрибутов, которые вы можете использовать в своей теме, см. в таблице атрибутов на сайте R.styleable.Theme . При добавлении стилей для представлений в макете вы также можете найти атрибуты, просматривая таблицу «Атрибуты XML» в справочниках по классам представлений. Например, все представления поддерживают атрибуты XML из базового класса View .

Большинство атрибутов применяются к определенным типам представлений, а некоторые применяются ко всем представлениям. Однако некоторые атрибуты темы, перечисленные в R.styleable.Theme применяются к окну активности, а не к представлениям в макете. Например, windowBackground изменяет фон окна, а windowEnterTransition определяет анимацию перехода, которая будет использоваться при запуске действия. Дополнительные сведения см. в разделе Запуск действия с помощью анимации .

Библиотека поддержки Android также предоставляет другие атрибуты, которые вы можете использовать для настройки темы, расширенной из Theme.AppCompat , например атрибут colorPrimary , показанный в предыдущем примере. Их лучше всего просматривать в файле библиотеки attrs.xml .

В библиотеке поддержки доступны также другие темы, которые вы, возможно, захотите расширить вместо тех, которые показаны в предыдущем примере. Лучшее место для просмотра доступных тем — это файл библиотеки themes.xml .

Добавить стили для конкретной версии

Если в новой версии Android добавлены атрибуты темы, которые вы хотите использовать, вы можете добавить их в свою тему, сохраняя при этом совместимость со старыми версиями. Все, что вам нужно, это еще один файл styles.xml сохраненный в каталоге values , который включает квалификатор версии ресурса :

res/values/styles.xml        # themes for all versions
res/values-v21/styles.xml    # themes for API level 21+ only

Поскольку стили в values/styles.xml доступны для всех версий, ваши темы values-v21/styles.xml могут их наследовать. Это означает, что вы можете избежать дублирования стилей, начав с «базовой» темы, а затем расширив ее стилями для конкретной версии.

Например, чтобы объявить переходы окон для Android 5.0 (уровень API 21) и выше, необходимо использовать новые атрибуты. Итак, ваша базовая тема в res/values/styles.xml может выглядеть так:

<resources>
    <!-- Base set of styles that apply to all versions. -->
    <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/primaryColor</item>
        <item name="colorPrimaryDark">@color/primaryTextColor</item>
        <item name="colorAccent">@color/secondaryColor</item>
    </style>

    <!-- Declare the theme name that's actually applied in the manifest file. -->
    <style name="AppTheme" parent="BaseAppTheme" />
</resources>

Затем добавьте стили для конкретной версии в res/values-v21/styles.xml следующим образом:

<resources>
    <!-- extend the base theme to add styles available only with API level 21+ -->
    <style name="AppTheme" parent="BaseAppTheme">
        <item name="android:windowActivityTransitions">true</item>
        <item name="android:windowEnterTransition">@android:transition/slide_right</item>
        <item name="android:windowExitTransition">@android:transition/slide_left</item>
    </style>
</resources>

Теперь вы можете применить AppTheme в файле манифеста, и система выберет стили, доступные для каждой версии системы.

Дополнительные сведения об использовании альтернативных ресурсов для разных устройств см. в разделе Предоставление альтернативных ресурсов .

Настройте стили виджетов

Каждый виджет в структуре и библиотеке поддержки имеет стиль по умолчанию. Например, когда вы оформляете свое приложение с помощью темы из библиотеки поддержки, экземпляр Button оформляется с использованием стиля Widget.AppCompat.Button . Если вы хотите применить к кнопке другой стиль виджета, вы можете сделать это с помощью атрибута style в файле макета. Например, в следующем примере применяется стиль кнопок библиотеки без полей:

<Button
    style="@style/Widget.AppCompat.Button.Borderless"
    ... />

Если вы хотите применить этот стиль ко всем кнопкам, вы можете объявить его в buttonStyle вашей темы следующим образом:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item>
    ...
</style>

Вы также можете расширить стили виджетов, как и любой другой стиль , а затем применить свой собственный стиль виджета в своем макете или теме.

Дополнительные ресурсы

Чтобы узнать больше о темах и стилях, посетите следующие дополнительные ресурсы:

Сообщения в блоге