Android のスタイルとテーマを使用すると、ウェブデザインのスタイルシートと同様に、アプリデザインの詳細を UI 構造や動作から分離できます。
スタイルは、1 つの View
の外観を指定する属性のコレクションです。スタイルでは、フォントの色、フォントサイズ、背景色などの属性を指定できます。
テーマとは、個々のビューだけでなく、アプリ全体、アクティビティ全体、またはビュー階層に適用される属性の集まりです。テーマを適用すると、アプリやアクティビティのすべてのビューに、サポートするテーマの各属性が適用されます。テーマでは、ステータスバーやウィンドウの背景など、ビュー以外の要素にもスタイルを適用できます。
スタイルとテーマは、res/values/
内のスタイル リソース ファイル(通常は styles.xml
という名前)で宣言します。
テーマとスタイル
テーマとスタイルには多くの類似点がありますが、用途は異なります。テーマとスタイルの基本構造は同じです。つまり、属性をリソースにマッピングする Key-Value ペアです。
スタイルは、特定のタイプのビューの属性を指定します。たとえば、あるスタイルでボタンの属性を指定できます。スタイルで指定するすべての属性は、レイアウト ファイルで設定できる属性になります。スタイルにすべての属性を抽出すると、複数のウィジェットで属性を使用および管理しやすくなります。
テーマは、スタイル、レイアウト、ウィジェットなどで参照可能な名前付きリソースのコレクションを定義します。テーマは、セマンティック名(colorPrimary
など)を Android リソースに割り当てます。
スタイルとテーマは連携して動作するように作られています。たとえば、スタイルで、ボタンのある部分を colorPrimary
にし、別の部分を colorSecondary
に指定したとします。これらの色の実際の定義はテーマで提供されます。デバイスが夜間モードになると、アプリは「ライト」モードから「ダークモード」に切り替わり、すべてのリソース名の値を変更できます。スタイルは特定の色の定義ではなくセマンティックな名前を使用しているため、スタイルを変更する必要はありません。
テーマとスタイルの連携について詳しくは、ブログ投稿 Android のスタイル設定: テーマとスタイルをご覧ください。
スタイルを作成して適用する
新しいスタイルを作成するには、プロジェクトの res/values/styles.xml
ファイルを開きます。作成するスタイルごとに、次の手順を行います。
- スタイルを一意に識別する名前を持つ
<style>
要素を追加します。 - 定義するスタイル属性ごとに
<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" ... />
スタイルで指定した各属性は、ビューで受け入れられる場合、そのビューに適用されます。ビューは、受け入れない属性を無視します。
ただし、通常は、個々のビューにスタイルを適用するのではなく、このガイドの別のセクションで説明するように、アプリ全体、アクティビティ、ビューのコレクションにテーマとしてスタイルを適用します。
スタイルを拡張しカスタマイズする
独自のスタイルを作成する場合は、プラットフォームの UI スタイルとの互換性を維持するため、常にフレームワークまたはサポート ライブラリから既存のスタイルを拡張してください。スタイルを拡張するには、parent
属性で拡張するスタイルを指定します。その後、継承したスタイル属性をオーバーライドして、新しい属性を追加できます。
たとえば、Android プラットフォームのデフォルトのテキスト外観を継承し、次のように変更できます。
<style name="GreenText" parent="@android:style/TextAppearance"> <item name="android:textColor">#00FF00</item> </style>
ただし、コアアプリのスタイルは常に Android サポート ライブラリから継承してください。サポート ライブラリのスタイルは、各バージョンで使用可能な UI 属性に合わせて各スタイルを最適化することで互換性を実現しています。多くの場合、サポート ライブラリのスタイルの名前はプラットフォームのスタイルと類似していますが、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 属性」の表をご覧ください。すべてのビューは基本の View
クラスの XML 属性をサポートしており、多くのビューは独自の特別な属性を追加します。たとえば、TextView
XML 属性には、入力を受け取るテキストビュー(EditText
ウィジェットなど)に適用できる android:inputType
属性が含まれています。
スタイルをテーマとして適用する
テーマは、スタイルの作成と同じ方法で作成できます。違いは、ビューに style
属性を使用してスタイルを適用するのではなく、AndroidManifest.xml
ファイルの <application>
タグまたは <activity>
タグに android:theme
属性を使用してテーマを適用します。
たとえば、Android サポート ライブラリのマテリアル デザインの「ダーク」テーマをアプリ全体に適用する方法は次のとおりです。
<manifest ... > <application android:theme="@style/Theme.AppCompat" ... > </application> </manifest>
また、「ライト」テーマを 1 つのアクティビティのみに適用する方法は次のとおりです。
<manifest ... > <application ... > <activity android:theme="@style/Theme.AppCompat.Light" ... > </activity> </application> </manifest>
アプリまたはアクティビティのすべてのビューに、指定されたテーマで定義されているスタイルから、サポート対象のスタイルが適用されます。ビューが、スタイルで宣言された一部の属性のみをサポートしている場合、それらの属性のみが適用され、サポートしていない属性は無視されます。
Android 5.0(API レベル 21)と Android サポート ライブラリ v22.1 以降では、レイアウト ファイル内のビューに android:theme
属性を指定することもできます。これにより、そのビューと子ビューのテーマが変更されます。これは、インターフェースの特定の部分でテーマのカラーパレットを変更する場合に便利です。
上記の例は、Android サポート ライブラリが提供する Theme.AppCompat
などのテーマを適用する方法を示しています。ただし、通常はアプリのブランドに合わせてテーマをカスタマイズする必要があります。そのための最善の方法は、次のセクションで説明するように、サポート ライブラリからこれらのスタイルを拡張し、一部の属性をオーバーライドすることです。
スタイル階層
Android では、Android アプリ全体で属性を設定するさまざまな方法が用意されています。たとえば、レイアウト内で属性を直接設定したり、ビューにスタイルを適用したり、レイアウトにテーマを適用したり、プログラムで属性を設定したりできます。
アプリのスタイル設定方法を選択するときは、Android のスタイル階層に注意してください。通常は、一貫性を保つためにテーマとスタイルを可能な限り使用してください。複数の場所で同じ属性を指定した場合、最終的に適用される属性は次のリストによって決まります。このリストは、優先度の高いものから順に並べられています。
TextView
から派生したクラスに、テキストスパンを使用して文字レベルまたは段落レベルのスタイル設定を適用する。- プログラムによる属性の適用
- 個々の属性をビューに直接適用する。
- ビューにスタイルを適用する
- デフォルトのスタイル。
- ビューのコレクション、アクティビティ、またはアプリ全体にテーマを適用する。
TextView
でTextAppearance
を設定するなど、特定のビュー固有のスタイル設定を適用する。
TextAppearance
スタイルに関する制限として、View
にはスタイルを 1 つしか適用できません。ただし、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 でプロジェクトを作成すると、プロジェクトの styles.xml
ファイルで定義されているように、デフォルトでアプリにマテリアル デザイン テーマが適用されます。この AppTheme
スタイルはサポート ライブラリのテーマを拡張し、アプリバーやフローティング アクション ボタン(使用されている場合)などの主要な UI 要素で使用される色属性のオーバーライドを含みます。そのため、指定された色を更新することで、アプリのカラーデザインを簡単にカスタマイズできます。
たとえば、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
ファイルで定義された他のカラーリソースへの参照です。これが、色を変更するために編集したファイルです。
ダイナミック カラーと追加のカスタムカラーを使用してユーザー エクスペリエンスを改善するには、マテリアル デザイン カラーの概要をご覧ください。
色を確認したら、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 属性」の表で属性を見つけることもできます。たとえば、すべてのビューはベースの View
クラスの XML 属性をサポートしています。
ほとんどの属性は特定のタイプのビューに適用されますが、一部の属性はすべてのビューに適用されます。ただし、R.styleable.Theme
にリストされている一部のテーマ属性は、レイアウト内のビューではなくアクティビティ ウィンドウに適用されます。たとえば、windowBackground
はウィンドウ背景を変更し、windowEnterTransition
はアクティビティの開始時に使用する遷移アニメーションを定義します。詳しくは、アニメーションを使ってアクティビティを起動するをご覧ください。
Android サポート ライブラリには、上記の例の colorPrimary
属性など、Theme.AppCompat
から拡張されたテーマのカスタマイズに使用できる他の属性も用意されています。これらはライブラリの attrs.xml
ファイルで表示することをおすすめします。
また、サポート ライブラリには、上記の例ではなく拡張できるテーマもあります。利用可能なテーマを確認するには、ライブラリの themes.xml
ファイルをご覧ください。
バージョン固有のスタイルを追加する
新しいバージョンの Android で使用したいテーマ属性が追加された場合、古いバージョンとの互換性を維持しながら、テーマに属性を追加できます。必要なのは、リソース バージョン修飾子を含む values
ディレクトリに保存されている別の styles.xml
ファイルだけです。
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>
また、他のスタイルを拡張する場合と同様にウィジェット スタイルを拡張してから、レイアウトやテーマにカスタム ウィジェット スタイルを適用することもできます。
参考情報
テーマとスタイルについて詳しくは、以下の参考情報をご覧ください。