Стили и темы

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

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

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

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

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

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

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

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

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

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

Стили и темы предназначены для совместной работы. Например, у вас может быть стиль, который указывает, что одна часть кнопки имеет 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/ `, как показано в предыдущем примере. Например, следующий пример наследует стили оформления текста от библиотеки Support:

<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 Support Library версии 22.1, вы также можете указать атрибут android:theme для представления в файле разметки. Это изменяет тему для этого представления и любых дочерних представлений, что полезно для изменения цветовых палитр темы в определенной части вашего интерфейса.

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

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

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

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

  1. Применение стилей на уровне символов или абзацев с использованием текстовых элементов span к классам, производным от 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 расширяет тему из библиотеки Support Library и включает переопределения для цветовых атрибутов, используемых ключевыми элементами пользовательского интерфейса, такими как панель приложения и плавающая кнопка действия , если она используется. Таким образом, вы можете быстро настроить цветовой дизайн вашего приложения, обновив предоставленные цвета.

Например, ваш файл 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>

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

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

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

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