Статьи

Пользовательский интерфейс Android: темы и стили

Эта статья является частью нашего Академического курса под названием Android UI Design — Основы .

В этом курсе вы познакомитесь с основами дизайна пользовательского интерфейса Android. Вы поймете пользовательский ввод, представления и макеты, а также адаптеры и фрагменты. Проверьте это здесь !

1. Введение

В предыдущих статьях мы говорили о макете и о том, как мы можем организовать наши Views так, чтобы мы могли создавать привлекательные пользовательские интерфейсы. Мы видели, что есть несколько layout managers и View s предоставляемых Android SDK, и что, если их недостаточно, мы можем создать собственные layout manager и View . Мы также говорили о drawable , что очень полезно, когда мы хотим настроить какой-то виджет.

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

В то время как макет и Views определяют структуру пользовательского интерфейса, стили и темы определяют их внешний вид. Что такое тема в Android?

Тема — это набор стилей, который можно применять ко всему приложению или к одному Activity . Это помогает создать привлекательный пользовательский интерфейс. Стиль, с другой стороны, определяет набор свойств, которые влияют на то, как выглядит Window или вид. Эти свойства определяют размер шрифта, семейство шрифтов, цвет фона, цвет шрифта и т. Д. Мы можем представить, что стиль похож на CSS на веб-странице, он отделяет структуру контента от того, как он отображается на экране.

Когда мы создаем макет в XML, мы используем layout managers и Views . При использовании Views мы можем указать, например, цвет фона, цвет шрифта, размер View и так далее. Например, давайте предположим, что у нас есть простой TextView подобный показанному ниже:

1
2
3
4
5
6
7
8
9
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#FF0000"
    android:text="Hello style"
    android:textColor="#FFFFFF"
    android:textSize=""14sp"" >
 
</TextView>

Глядя на приведенный выше код, мы замечаем, что есть некоторые ошибки: мы добавили в View не только информацию, касающуюся его содержимого, но также информацию о том, как он выглядит, и мы жестко закодировали его. Это очень плохая практика, потому что если мы хотим изменить цвет текста, мы должны искать каждый TextView в нашем определении пользовательского интерфейса.

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

Стили и темы — это очень похожие понятия: когда мы применяем стиль к Activity или приложению, а не применяем его к одному View , мы называем его темой. В этом случае каждое свойство View , принадлежащее Activity / приложению, будет определено стилем Activity / приложения. Например, мы можем определить размер и цвет текста в стиле и применить его к Activity . Таким образом, все тексты будут выглядеть так, как определено в стиле.

2. Определение стиля

Теперь, когда мы знаем, что такое стиль, мы должны определить его внутри нашего приложения. Для этого нам нужно создать XML-файл в разделе res/values . Мы можем выбрать имя файла по своему усмотрению, но оно должно иметь расширение .xml . Стиль определяется внутри тега ресурса. Итак, мы имеем:

01
02
03
04
05
06
07
08
09
10
11
12
<resources xmlns:android="http://schemas.android.com/apk/res/android" >
 
    <style
        name="MyTextStyle"
        parent="@android:style/TextAppearance" >
 
        <item name="android:textColor">#FF0000</item>
 
        <item name="android:textSize">14sp</item>
    </style>
 
</resources>

Таким образом, мы определили новый стиль под названием MyTextStyle и мы определили некоторые свойства, как указано в тегах элементов. Обратите внимание, что в определении стиля мы использовали родительский атрибут. Это необязательный атрибут, который можно использовать, если мы хотим, чтобы определенный стиль наследовал его свойства от родительского стиля. Затем внутри определения стиля мы можем переопределить родительские свойства. Под тегом style мы определили два элемента, поэтому мы указали два свойства.

Тег item имеет атрибут name, который определяет имя свойства. Это имя свойства, к которому мы хотим применить стиль, а содержимое тега — это значение свойства. В нашем случае мы определили свойство с именем android:textColor присвоив ему значение #FF0000 а другое с именем android:textSize и присвоили значение 14sp .

2.1. наследование

Как мы уже видели, стиль может наследоваться от родительского стиля, используя родительский атрибут в теге style . Таким образом, мы можем создать иерархическую структуру со стилями. Есть другой способ реализовать иерархическую структуру в том же файле стиля XML: мы можем просто использовать . нотации.

Например, мы можем предположить, что мы хотим создать другой стиль с именем MyTextStyleHuge который наследуется от MyTextStyle но переопределяет размер текста:

1
2
3
<style name="MyTextStyle.MyTextStyleHuge" >
    <item name="android:textSize">30sp</item>
</style>

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

2.2. Свойства стиля

Каждый стиль определяет значения набора свойств, используя тег элемента. Имена свойств — это имена свойств, определенных View . Например, глядя на TextView мы замечаем, что у него есть набор свойств, описанных в документации в разделе атрибутов XML. Если мы хотим определить стиль одного из этих свойств, мы должны использовать то же имя в имени атрибута тега item .

Глядя на приведенный выше пример, мы использовали свойства android:textSize и android:textColor , они являются двумя свойствами TextView соответствии с документацией: первое используется для определения размера текста, а другое — для цвета текста.

Как только мы определили наш стиль, мы должны применить его. Как было сказано ранее, мы можем применить его к одному View , к Activity или к приложению. Например, если мы хотим применить стиль к одному View мы используем атрибут style следующим образом:

1
2
3
4
5
<TextView
    style="@style/MyTextStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Text with style" />

Теперь мы применили MyTextStyle к TextView . Эти два способа эквивалентны:

1
2
3
4
5
6
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello without style"
    android:textColor="#FF0000"
    android:textSize=""14dp"" >
1
2
3
4
5
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Text with style"
    style="@style/MyTextStyle"/>

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

фигура 1

фигура 1

Как вы можете заметить, результат одинаков для обоих TextView .

3. Создание и применение тем

Мы знаем, что тема — это особый стиль, который применяется к Activity или приложению, а не к одному View . Тема — это всегда стиль, и когда мы хотим определить тему, мы используем ту же технику, которая использовалась ранее при определении стиля, поэтому мы создаем файл XML в res/values . Android предоставляет большую коллекцию тем и стилей, которые мы можем использовать или изменить их настройку.

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

1
2
3
4
5
6
7
<style
    name="AllGreen"
    parent="@android:style/Theme.Black" >
 
    <item name="android:background">#00FF00</item>
 
</style>

и затем мы применяем его к приложению в Manifest.xml :

1
2
3
4
5
6
<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AllGreen" >
 
</application>

Запустив подобное приложение, мы получим следующий результат:

фигура 2

фигура 2

В результате фон Activity становится зеленым, как мы и хотели. TextView мы определили стиль для TextView и теперь мы хотели бы использовать его в нашей теме. Чтобы сделать это, мы должны немного его изменить:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<resources xmlns:android="http://schemas.android.com/apk/res/android" >
 
    <style
        name="MyTextStyle"
        parent="@android:style/Widget.Text&lt;code>View&lt;/code>" >
 
        <item name="android:textColor">#FF0000</item>
 
        <item name="android:textSize">14sp</item>
    </style>
 
    <style
        name="AllGreen"
        parent="@android:style/Theme.Black" >
 
        <item name="android:background">#00FF00</item>
 
        <item name="android:textViewStyle">@style/MyTextStyle</item>
    </style>
 
</resources>

Запустив приложение мы имеем:

Рисунок 3

Рисунок 3

К настоящему времени мы использовали только сплошной цвет для фона, и мы увидели, что легко изменить фон, но что, если мы хотим использовать цвет градиента?

В предыдущей статье мы описали, как создать градиент: мы должны создать файл с расширением XML в каталоге res/drawable ; мы называем это grandient_red.xml :

1
2
3
4
5
6
7
8
 
    <gradient
        android:endColor="#AA0000"
        android:startColor="#FF0000"
        android:type="linear" />
 
</shape>

Теперь мы должны ссылаться на него в нашем стиле, и для простоты мы можем создать другой файл стиля с именем style_gradient.xml :

01
02
03
04
05
06
07
08
09
10
<resources xmlns:android="http://schemas.android.com/apk/res/android" >
 
    <style
        name="RedGrad"
        parent="@android:style/Theme.Black" >
 
        <item name="android:background">@drawable/gradient_red</item>
    </style>
 
</resources>

Как вы можете заметить, мы ссылались на drawable мы создали в каталоге drawable , используя @drawable/file_name . Запустив приложение с этим стилем, мы имеем:

Рисунок 4

Рисунок 4

До сих пор всякий раз, когда мы определяли цвета или размеры шрифтов, мы использовали некоторые жестко закодированные значения. Даже если это возможно, это не рекомендуется по нескольким причинам:

  1. Если мы хотим изменить цвет или размер шрифта, например, мы должны искать эти значения в файле стиля.
  2. Мы хотели бы изменить размер шрифта и цвета в соответствии с версией платформы, например, или в соответствии с размерами экрана.

Поэтому рекомендуется перенести определение цвета и / или размер шрифта и т. Д. На внешние ресурсы и ссылаться на них в стиле.

Итак, давайте перепишем текстовый стиль, который мы использовали ранее, где на этот раз мы пишем стиль в XML-файле с именем style_text.xml :

01
02
03
04
05
06
07
08
09
10
<resources>
 
    <style name="MyTextStyle1" >
 
        <item name="android:textColor">@color/red</item>
 
        <item name="android:textSize">@dimen/myTextSize</item>
    </style>
 
</resources>

В этом стиле мы ссылались на внешний ресурс, который устанавливает цвет текста и размер текста. В этом случае нам нужно создать два файла: один, который мы можем вызвать colors.xml содержащий определение цвета, и другой, содержащий измерение, называемое dimens.xml :

1
2
3
4
5
6
<resources>
    <color name="red">#FF0000</color>
</resources>
<resources>
    <dimen name="myTextSize">14sp</dimen>
</resources>

Теперь мы знаем, что мы можем ссылаться на внешние ресурсы, используя символ @ , но иногда мы хотим ссылаться на один элемент стиля, а не весь стиль.

Например, мы хотим сослаться на текущий цвет текста, но мы не знаем, какой из них будет использоваться ОС. Как мы можем сделать это? Ну, Android обеспечивает ? символ, который мы можем использовать для доступа к одному элементу. Например, мы можем предположить, что мы хотим установить значение цвета текста, определенное в ОС Android:

1
2
3
4
5
<style name="TextRef" >
 
    <item name="android:textColor">?android:attr/textColorLink</item>
 
</style>

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

Рисунок 5

Рисунок 5

3.1. Темы и платформы

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

До сих пор мы использовали только res/values и создали несколько файлов, которые представляют стили, размеры, цвета и так далее. Android может использовать разные ресурсы в зависимости от версии платформы, поэтому мы можем адаптировать, например, наши темы и стили к версии платформы, или мы можем даже создать другой стиль с разными цветами в зависимости от платформы.

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

Чтобы создать набор ресурсов, который зависит от версии платформы, мы должны создать каталог с именем res под названием values-vxx где xx — уровень API; например, если мы хотим создать набор ресурсов, подходящий для Android 3.0 (уровень API 11) или выше, мы можем создать каталог под названием values-v11 . Под этим каталогом мы создаем стиль и темы. Если мы заметим, что когда мы используем Eclipse в качестве IDE, по умолчанию создаются две темы, одна в разделе res/values :

1
<style name="AppBaseTheme" parent="android:Theme.Light">

и еще один в res/values-v11 :

1
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">

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

Мы можем указать не только нашу тему в зависимости от версии платформы, но и в зависимости от размера экрана. Например, если мы хотим применить нашу тему, когда наименьший размер экрана составляет не менее 600dp , мы можем создать каталог values-sw600dp и создать под ним наш файл стиля. Этот стиль и тема будут применяться только в том случае, если наименьший размер экрана устройства составляет не менее 600dp . Эта техника полезна, когда мы хотим предоставить другой стиль / тему в соответствии с размером экрана. Мы могли бы, например, иметь только один стиль / тему, определенные в res/values и предоставить другой размер текста в зависимости от размера экрана. В этом случае мы можем создать только файл под dimens.xml .

4. Вывод

Теперь мы знаем, как использовать стили и темы, и полезно вспомнить некоторые основные правила, которым мы должны следовать:

  1. Не используйте жестко закодированные значения для цветов, размера и так далее.
  2. Определите стиль или тему и используйте style=”...” в определении виджета для ссылки на стиль.
  3. В определении стиля не следует использовать значения непосредственно в файле XML, а ссылаться на тему, используя внешние ресурсы. Например, @color/color_name цвет, используя @color/color_name .
  4. Предоставляет другой стиль или тему в зависимости от версии платформы.
  5. Предоставляет различные ресурсы в зависимости от размера экрана.

5. Загрузите исходный код

Это был урок о том, как использовать темы и стили Android. Вы можете скачать исходный код здесь: themeStyle.zip