1. 始める前に
マテリアル デザインは Google が開発したデザイン システムです。Android やその他のモバイル プラットフォーム、ウェブ プラットフォームで、高品質なデジタル エクスペリエンスを実現します。マテリアル デザインは現実世界とそのテクスチャに基づいており、物体の光の反射や影などの表現が可能です。見やすく魅力的なアプリの UI を一貫したデザインで作成するためのガイドラインとして利用できます。
この Codelab では、アプリでマテリアル デザインを使用するためのマテリアル テーマ設定と、色、タイポグラフィ、シェイプのカスタマイズについて学習します。アプリは必要に応じて少しだけでも大きくでもカスタマイズできます。また、トップ アプリバーを追加してアプリの名前やアイコンを表示する方法もわかります。
前提条件
- Kotlin 言語(構文、関数、変数など)に精通している。
- パディングのある行と列を含め、Compose でレイアウトを作成できる。
- Compose で簡単なリストを作成できる。
学習内容
- Compose アプリにマテリアル テーマを適用する方法
- アプリにカスタム フォントを追加する方法
- アプリにカスタム カラーパレットを追加する方法
- アプリ内の要素にカスタム シェイプを追加する方法
- アプリにトップ アプリバーを追加する方法
作成するアプリの概要
- マテリアル デザインのベスト プラクティスを取り入れた、洗練されたアプリを作成します。
必要なもの
- Android Studio の最新バージョン
- スターター コードとフォントをダウンロードするためのインターネット接続
2. Code-Along 動画を見る(省略可)
コースの講師が Codelab を完了する様子を視聴する場合は、以下の動画を再生してください。
動画を拡大して全画面表示にすることをおすすめします(動画の右下隅のアイコン を使用します)。そうすれば、Android Studio とコードがもっとはっきり見えるようになります。
このステップは省略可能です。動画をスキップして、すぐに Codelab の学習を開始することもできます。
3. アプリの概要
この Codelab では、犬のリストを表示するアプリ、Woof を作成します。Woof ではマテリアル デザインを使用して洗練されたアプリ エクスペリエンスを実現します。
Woof アプリでは、デザイナーと協力して、アプリのカラーパレット、タイポグラフィ、シェイプの選択などを行っています。この Codelab では、デザイナーの協力の有無にかかわらず、マテリアル テーマ設定によってできることを説明します。この Codelab を通じて、アプリのデザインをマテリアル テーマ設定によって改善するためのアイデアが得られます。
デザイナーから提供されたデザイン仕様を以下に示します。ライトモードとダークモードにおけるアプリのビジュアル デザインの詳細です。
アプリのデザイン:
ライトモード | ダークモード |
カラーパレット
デザイナーが選んだライトモードとダークモードのカラーパレットを以下に示します。
ライト:
色 | 名前 | 16 進数色コード | スロット |
Grey50 | #F8F9FA | primary | |
Green50 | #E6F4EA | surface | |
Green100 | #CEEAD6 | background | |
Grey700 | #5F6368 | secondary | |
Grey900 | #202124 | onSurface | |
Grey900 | #202124 | onPrimary |
ダーク:
色 | 名前 | 16 進数色コード | スロット |
White | #FFFFFF | primary | |
Grey100 | #F1F3F4 | onSurface | |
Grey100 | #F1F3F4 | onPrimary | |
Cyan700 | #129EAF | surface | |
Cyan900 | #007B83 | background | |
Grey900 | #202124 | secondary |
タイポグラフィ
デザイナーが選んだアプリのフォントを以下に示します。
見出し | フォント | フォントの太さ | サイズ |
h1 | 標準 | 30 sp | |
h2 | 太字 | 20 sp | |
h3 | 太字 | 14 sp | |
body1 | 標準 | 14 sp |
テーマファイル
Theme.kt ファイルは、アプリのテーマに関するすべての情報を保持するファイルです。色、タイポグラフィ、シェイプによって定義されます。Theme.kt に Codelab で変更を加えるのは 1 回だけですが、これは重要なファイルです。Theme.kt ファイルには、アプリの色、タイポグラフィ、シェイプを設定するコンポーザブル WoofTheme()
があります。
@Composable
fun WoofTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
MainActivity.kt では、WoofTheme()
を追加することでマテリアル テーマ設定が定義されます。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WoofTheme {
WoofApp()
}
}
}
}
DefaultPreview()
をご覧ください。また WoofTheme()
を追加することで、[Preview] タブにマテリアル テーマ設定が表示されます。
@Preview
@Composable
fun DefaultPreview() {
WoofTheme(darkTheme = false) {
WoofApp()
}
}
4. スターター コードを取得する
- プロジェクト用に提供されている GitHub リポジトリ ページに移動します。
- [Code] ボタンをクリックします。ダイアログが開きます。
- ダイアログで [HTTPS] タブをクリックし、URL の横にある
をクリックしてコピーします。この URL は Android Studio で使用します。
- Android Studio が開いていない場合は起動し、[Welcome to Android Studio] ウィンドウで [Get from VCS] をクリックします。
- Android Studio がすでに開いている場合は、[File] > [New] > [Project from Version Control] を選択します。
- [Get from Version Control] ウィンドウの [Version control] メニューで、[Git] を選択します。
- [URL] テキスト ボックスに、GitHub リポジトリ ページからコピーしたリンクを貼り付けます。
- [Directory] メニューで、GitHub リポジトリのソースコードのクローンを作成するディレクトリを選択します。
- [Clone] をクリックします。
- Android Studio がプロジェクトのダウンロードを終えて、それを開くまで待ちます。
- Android Studio のナビゲーション メニューで [
Run app] をクリックし、アプリが想定どおりにビルドされたことを確認します。
- ナビゲーション メニューで、[Git] > [Branches] をクリックします。
- [Remote Branches] の [Git Branches] ダイアログで、前に指定したブランチ名を選択して [Checkout] をクリックします。
- ブランチを切り替える必要がある場合は、[Git] > [Branches] をクリックし、切り替え先のブランチを選択して [Smart Checkout] をクリックします。
スターター コードを確認する
- Android Studio でスターター コードを開きます。
- [com.example.woof] > [data] > [Dog.kt] を開きます。これには、犬の写真、名前、年齢、特技を示す
Dog data class
が含まれます。また、犬のリストや、アプリのデータとして使用する情報も含まれています。 - [res] > [drawable] を開きます。これには、アプリアイコン、犬の画像、アイコンなど、このプロジェクトに必要なすべての画像アセットが含まれています。
- [res] > [values] > [strings.xml] を開きます。このファイルには、アプリで使用する文字列(アプリ名、犬の名前、説明など)が含まれています。
- MainActivity.kt を開きます。このファイルには、犬の写真、名前、年齢を表示する簡単なリストを作成するコードが含まれています。
WoofApp()
には、DogItems
を表示するLazyColumn
が含まれています。DogItem()
には、犬の写真とその犬に関する情報を表示するRow
が含まれています。DogIcon()
は犬の写真を表示します。DogInformation()
には犬の名前と年齢が含まれています。
エミュレータ / デバイスがライトモードになっていることを確認する
この Codelab ではライトモードとダークモードの両方を使用しますが、ほとんどの場合はライトモードです。始める前に、デバイスまたはエミュレータがライトモードになっていることを確認してください。
アプリをライトモードで表示するには、エミュレータまたは実機で次のように操作します。
- デバイスの設定アプリを開きます。
- ダークモードを検索してクリックします。
- ダークモードがオンになっている場合は、オフにします。
スターター コードを実行すると、最初の画面が表示されます。犬の写真、名前、年齢を示すリストです。このままでも機能しますが、見た目が良くないので修正します。
5. 色を追加する
最初に Woof アプリのカラーパレットを変更します。
カラーパレットは、アプリで使用する色の組み合わせを示しています。色の組み合わせによってムードが変わり、アプリを使用するユーザーの感じ方に影響します。このアプリについては、デザイナーがカラーパレットを選びました。マテリアル デザインのウェブサイトには、カラーシステムのガイダンスが用意されています。カラーパレットとその作成方法について詳しく知ることができます。
Android アプリに色を追加する場合、従来は Color.RED
や Color.PINK
などを使用していました。セルリアン ブルーやジェイド グリーンのように、より具体的な色を追加する場合はどうすればよいでしょうか。
Android システムでは、色は 16 進数の色値で表わされます。16 進数色コードは番号記号(#)で始まり、その後に色の赤、緑、青(RGB)成分を表す 6 つの文字または数字が続きます。最初の 2 文字と数字は赤、次の 2 文字は緑、最後の 2 文字は青を表します。
色には、色の透明度を表す英字や数字のアルファ値を含めることもできます(#00 は不透明度 0%(完全に透明)、#FF は不透明度 100%(完全に不透明))。指定した場合、アルファ値は 16 進数色コードで番号記号(#)に続く最初の 2 文字です。アルファ値を指定しない場合は、#FF(不透明度 100%)とみなされます。
以下に、16 進数色コードの例を示します。
色 | 名前 | 16 進数色コード |
Black | #000000 | |
Green | #72D98C | |
Blue | #4285F4 | |
White | #FFFFFF |
各色の 16 進数色コードを覚えておく必要はありません。色選択ツールによって自動的に数字が生成されます。この Codelab ではあらかじめ色が用意されています。
次に、アプリで使用するカラーパレットを示します。アルファ値はなく、つまり色の不透明度は 100% になっています。
ライト:
色 | 名前 | 16 進数色コード | スロット |
Grey50 | #F8F9FA | primary | |
Green50 | #E6F4EA | surface | |
Green100 | #CEEAD6 | background | |
Grey700 | #5F6368 | secondary | |
Grey900 | #202124 | onSurface | |
Grey900 | #202124 | onPrimary |
スロットとは何でしょうか。またどのように割り当てられるのでしょうか。
- プライマリ(primary)カラーとは、アプリの画面やコンポーネントで最も多く表示される色です。
- セカンダリ(secondary)カラーは、アプリにアクセントを付け、目立たせるために使用する色です。
- サーフェス(surface)色は、コンポーネントの表面(カード、シート、メニューなど)に影響します。
- 背景(background)色は、スクロール可能なコンテンツの背後の色です。
- オンカラー要素は、パレット内の他の色の上に配置され、主にテキスト、アイコン、ストロークに適用されます。カラーパレットでは、サーフェス色の上に表示される onSurface カラーと、プライマリ カラーの上部に表示される onPrimary カラーがあります。
これらのスロットによって一貫性のあるデザイン システムが実現し、関連するコンポーネントにも同様に色付けされるようになります。
特定のコンポーネントはカラースロットに自動的にマッピングされます。たとえば Surface
コンポーザブルでは、サーフェス スロットに背景色が自動的にマッピングされます。つまり、Surface
コンポーザブルにサーフェスの色を明示的に割り当てる必要はありません。アプリでカラーテーマを設定すると、その色が自動的に表示されます。ここに挙げた 6 つ以外にもカラースロットはありますが、必ずしもすべてに色を割り当てる必要はありません。アプリのテーマで指定されていない色は、ベースラインのマテリアル カラーテーマで定義された色にフォールバックします。それによってアプリのデフォルトのテーマが定義されます。
色に関する理論的な話は以上です。次にこの美しいカラーパレットをアプリに追加してみましょう。
テーマにカラーパレットを追加する
- Color.kt ファイルを開きます。このファイルは、アプリのカラーパレットに色を追加するために使用されます。デフォルトのカラーパレットにマッピングされる色がすでにいくつか追加されています。Woof アプリのカラーパレットに必要なこれらの新しい色を、すでに指定されている色に追加します。
//Light Theme
val Grey50 = Color(0xFFF8F9FA)
val Grey900 = Color(0xFF202124)
val Grey700 = Color(0xFF5F6368)
val Green50 = Color(0xFFE6F4EA)
val Green100 = Color(0xFFCEEAD6)
- Theme.kt ファイルを開き、
LightColorPalette
を以下のコードに置き換えて、スロットに色を追加します。
private val LightColorPalette = lightColors(
background = Green100,
surface = Green50,
onSurface = Grey900,
primary = Grey50,
onPrimary = Grey900,
secondary = Grey700
)
WoofTheme()
は、darkTheme
が true に設定されているかを確認し、MaterialTheme
object
の colors
を、false の場合はライトカラー パレットに、true の場合はダークカラー パレットに設定します。
@Composable
fun WoofTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
アプリに色を追加する
次に、追加した色をアプリのさまざまな場所で使用します。以下のものを使用します。
- リストの背景になる
background
色 - リストの背景色に対して目立つように、リストアイテムの背景として適用する
surface
色 - リストアイテムの色に対して読みやすくするために、テキストに適用する
onSurface
色
他の 2 つの色は、この Codelab の後半で使用します。
- MainActivity.kt を開きます。
WoofApp()
でLazyColumn
に背景修飾子を追加して、リストの背景を緑色にします。Theme.kt でbackground
に設定した色を背景色に設定します。アプリテーマのbackground
色として設定した色には、MaterialTheme.colors.background
からアクセスできます。 - [Preview] タブで [Build & Refresh] をクリックします。
import androidx.compose.material.MaterialTheme
import androidx.compose.foundation.background
LazyColumn(modifier =
Modifier.background(MaterialTheme.colors.background))
よくできました。背景色が Green100
になりました。
DogItem()
でbackground()
拡張機能をRow
に追加し、MaterialTheme.colors.surface
に渡します。これにより、Row
の背景色が、アプリテーマで指定されたsurface
の色に設定されます。
import androidx.compose.ui.unit.dp
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
.background(MaterialTheme.colors.surface)
)
[プレビュー] タブでを見ると、リストアイテムの色がアプリの背景と異なり、各リストアイテムの色がより明瞭になっていることがわかります。
DogInformation()
で、犬の名前のテキストと犬の年齢のテキストのコンポーザブルにcolor
を追加します。それにより、この 2 つのテキスト コンポーザブルのフォントの色が変更されます。onSurface
色を使用します。
Column {
Text(
text = stringResource(dog.name),
color = MaterialTheme.colors.onSurface,
modifier = Modifier.padding(top = smallPadding)
)
Text(
text = stringResource(R.string.years_old, dog.age.toString()),
color = MaterialTheme.colors.onSurface
)
}
- アプリをビルドして更新します。犬の名前と年齢を表示するテキストは、背景とのコントラストが強く、読みやすくなっていますが、ライトモードではそれほど明瞭ではありません。
ライトモード
ダークモードの背景に対するテキストのコントラストを以下に示します。これを次のセクションで実装します。
テキストの色を設定していないダークモード | テキストの色を設定したダークモード |
ダークモード
Android システムには、デバイスをダークモードに切り替えるオプションがあります。ダークモードでは、より暗く、落ち着いた色が使用されており、以下の効果があります。
- 電力使用量を大幅に削減できます(削減できる量はデバイスの画面テクノロジーに左右されます)。
- 視力の低いユーザーや明るい光に敏感なユーザーにとって、画面の見やすさが向上します。
- すべてのユーザーにとって、暗い場所でのデバイスの使いやすさが向上します。
アプリでフォースダークにオプトインすると、システムによってダークモードが実装されます。ただし、ダークモードの実装はユーザー エクスペリエンス向上に有効であるため、アプリのテーマについてはデベロッパーが完全に制御できます。
デベロッパーが独自にダークモードを選択する際は、ダークモードの色がユーザー補助のコントラスト標準に適合していることをご確認ください。ダークモードでは暗いサーフェス色を使用し、色のアクセントは限定されます。
以下は、このアプリのダークモードの色です。
ダーク:
色 | 名前 | 16 進数色コード | スロット |
White | #FFFFFF | primary | |
Grey100 | #F1F3F4 | onSurface | |
Grey100 | #F1F3F4 | onPrimary | |
Cyan700 | #129EAF | surface | |
Cyan900 | #007B83 | background | |
Grey900 | #202124 | secondary |
ダークモードを追加する
- Color.kt で、ダークモードの色を追加します。ライトモードには
Grey900
がすでに追加されているため、追加されるのは 4 色のみとなっています。
//Dark Theme
val White = Color(0xFFFFFFFF)
val Grey100 = Color(0xFFF1F3F4)
val Cyan900 = Color(0xFF007B83)
val Cyan700 = Color(0xFF129EAF)
- デフォルトで用意されていた色は、不要になったので削除してください。以下に、この時点でファイルに含めるべき値を示します。
//Light Theme
val Grey50 = Color(0xFFF8F9FA)
val Grey900 = Color(0xFF202124)
val Grey700 = Color(0xFF5F6368)
val Green50 = Color(0xFFE6F4EA)
val Green100 = Color(0xFFCEEAD6)
//Dark Theme
val White = Color(0xFFFFFFFF)
val Grey100 = Color(0xFFF1F3F4)
val Cyan900 = Color(0xFF007B83)
val Cyan700 = Color(0xFF129EAF)
- Theme.kt ファイルで、既存の
DarkColorPalette
を以下の色に置き換えます。
private val DarkColorPalette = darkColors(
background = Cyan900,
surface = Cyan700,
onSurface = White,
primary = Grey900,
onPrimary = White,
secondary = Grey100
)
ダークモードをプレビュー表示する
ダークモードの動作を確認するには、別の Preview()
を MainActivity.kt に追加します。それにより、コードの UI レイアウトを変更したときに、ライトモードとダークモードのプレビューがどのように表示されるかを同時に確認できます。
DefaultPreview()
で、DarkThemePreview()
という新しい関数を作成し、@Preview
と@Composable
というアノテーションを付けます。
@Preview
@Composable
fun DarkThemePreview() {
}
DarkThemePreview()
内でWoofTheme()
を追加します。WoofTheme()
を追加しないと、アプリに追加したスタイルは表示されません。darkTheme
パラメータを true に設定します。
@Preview
@Composable
fun DarkThemePreview() {
WoofTheme(darkTheme = true) {
}
}
WoofTheme()
内でWoofApp()
を呼び出します。
@Preview
@Composable
fun DarkThemePreview() {
WoofTheme(darkTheme = true) {
WoofApp()
}
}
これで、Preview
セクションの [Build & Refresh] をクリックして下にスクロールすると、アプリがダークモードで表示されます。アプリ / リストアイテムの背景がさらに暗くなり、テキストが白くなります。ダークモードとライトモードの違いを比較できます。
ダークモード | ライトモード |
デバイスまたはエミュレータでダークモードを表示する
エミュレータまたは実機でアプリをダークモードで表示するには:
- デバイスの設定アプリを開きます。
- ダークモードを検索してクリックします。
- ダークモードをオンにします。
- Woof アプリを再度開くと、ダークモードで表示されます。
この Codelab ではライトモードに重点を置いているため、ダークモードをオフにしてからアプリの操作を進めてください。
- デバイスの設定アプリを開きます。
- [Display] を選択します。
- [Dark theme] をオフにします。
セクションの最初と現在とで、アプリの外観がどのように変わったかを比較してください。リストアイテムやテキストがより明瞭になり、カラーパターンの視覚的な魅力が増しているはずです。
色を使わない | 色を使う(ライトモード) | 色を使う(ダークモード) |
6. シェイプを追加する
デフォルトでは、アプリ内のシェイプはすべて長方形です。ただし、シェイプを適用すると、コンポーザブルのデザインが大幅に変わる場合があります。シェイプはユーザーの注意を引き、コンポーネントを明確に示し、状態を伝え、ブランドを表現するために役立ちます。
多くのシェイプは、角が丸い長方形を表す RoundedCornerShape
を使用して定義されています。渡される数値によって角の丸みが決まります。RoundedCornerShape(percent = 0)
を使用すると、長方形の角は丸くなりません。RoundedCornerShape(percent = 50)
を使用すると、角が完全な円形になります。マテリアル サイトでは、さらに複雑なシェイプを試せるように、シェイプ カスタマイズ ツールが用意されています。
0% | 25% | 50% |
Compose のコンポーネントのシェイプを定義するには、Shape.kt ファイルを使用します。コンポーネントには、大、中、小の 3 種類があります。このセクションでは、Card
コンポーネント(medium
サイズとして定義)を変更します。コンポーネントはサイズに基づいてシェイプ カテゴリにグループ化されます。
Image
はコンポーネントではないため、MainActivity.kt にシェーピングを追加します。
このセクションでは、犬の画像を丸くシェーピングし、リストアイテムのシェイプを変更します。
犬の画像を丸で囲む
- まず、犬の写真が表示されているアイコンを円形に変更します。MainActivity.kt を開きます。
DogIcon()
で、clip
属性をImage
のmodifier
に追加します。画像がシェイプにクリップされます。角を完全な円形にするには、RoundedCornerShape()
と 50 を渡します。
import androidx.compose.ui.draw.clip
import androidx.compose.foundation.shape.RoundedCornerShape
@Composable
fun DogIcon(@DrawableRes dogIcon: Int, modifier: Modifier = Modifier) {
Image(
modifier = modifier
.size(64.dp)
.padding(8.dp)
.clip(RoundedCornerShape(50)),
DefaultPreview
を見ると、犬のアイコンが円形になっていることがわかります。しかし、一部の写真の両側が切り取られ、完全な円形として表示されていません。
- すべての写真を円形にするには、
ContentScale
属性とCrop
属性を追加します。画像が収まるように切り抜かれます。contentScale
はImage
の属性であり、modifier
の一部ではありません。
import androidx.compose.ui.layout.ContentScale
@Composable
fun DogIcon(dogIcon: Int, modifier: Modifier = Modifier) {
Image(
modifier = modifier
.size(64.dp)
.padding(8.dp)
.clip(RoundedCornerShape(50)),
contentScale = ContentScale.Crop,
アプリを実行すると、アイコンが円形に表示されます。
リストアイテムにシェイプを追加する
このセクションでは、リストアイテムにシェイプを追加します。リストアイテムはすでに Row
内に表示されていますが、Row
はシェーピングできるようになっていません。代わりに、Row
を Card
に追加します。Card
は、サーフェスとして 1 つのコンポーザブルを含めることができ、また装飾オプションも用意されています。装飾は枠線、シェイプ、エレベーションなどを使用して追加できます。このセクションでは、Card
を使用してリストアイテムにシェイプを追加します。
DogItem()
で、Row
の周囲にCard
を追加します。
import androidx.compose.material.Card
@Composable
fun DogItem(dog: Dog, modifier: Modifier = Modifier) {
Card() {
Row(
- Shape.kt ファイルを開きます。
Card
はミディアム コンポーネントであるため、Shapes
オブジェクトの medium 属性を更新します。このアプリではリストの角を丸くしますが、完全な円形にする必要はありません。それには、16.dp
をmedium
属性に渡します。
val Shapes = Shapes(
small = RoundedCornerShape(4.dp),
medium = RoundedCornerShape(16.dp),
large = RoundedCornerShape(0.dp)
)
Card
はデフォルトでミディアム シェイプを使用しているため、明示的にミディアム シェイプに設定する必要はありません。プレビューを更新すると、角が丸くなったことがわかります。ただし、リストアイテム間にパディングはなく、リストアイテムの終了位置と次のリストアイテムの開始位置が不明確です。次に、リストアイテム間にパディングを追加して、各アイテム間の定義を作成します。
WoofTheme()
の Theme.kt ファイルに戻って MaterialTheme()
を見ると、shapes
属性が、更新した Shapes
val
に設定されていることがわかります。
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
修飾子を更新してパディングを追加する
Card
がDogItem()
に最初に表示されるコンポーザブルになったため、DogItem
コンポーザブルに渡す修飾子は、Row
ではなくCard
に転送する必要があります。Row
は、Modifier
の新しいインスタンスを使用するようになります。
@Composable
fun DogItem(dog: Dog, modifier: Modifier = Modifier) {
Card(
modifier = modifier
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
.background(MaterialTheme.colors.surface)
)
padding
をCard modifier
に追加し、8.dp
を渡して、各リストアイテムの周囲にパディングを追加します。
Card(
modifier = modifier.padding(8.dp)
)
プレビューを更新すると、各アイテム間にパディングがあるため、角の丸いリストアイテムがより明瞭に表示されます。
不明瞭な色
Card
は Surface
であり、Theme.kt ファイルでは surface
スロットに明示的に色が設定されています。そのため、Row
から色を削除できます。surface
の色に明示的に設定する必要はありません。
DogItem()
で、背景色の明示的な設定を削除します。
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
プレビューを更新します。明示的な色の割り当てを削除していますが、Row
の背景色が変わっていないことがわかります。
- 犬の名前と年齢の
Text
はSurface
の上に配置されるため、色はデフォルトでonSurface
になります。DogInformation()
の両方のText
アイテムについて、明示的な色設定を削除します。
コンポーザブルは次のようになります。
@Composable
fun DogInformation(@StringRes dogName: Int, dogAge: Int, modifier: Modifier = Modifier) {
Column {
Text(
text = stringResource(dogName),
modifier = modifier.padding(top = 8.dp)
)
Text(
text = stringResource(R.string.years_old, dogAge)
)
}
}
リストアイテムにエレベーションを追加する
リストアイテムのシェーピングを行ったため、アプリはきれいになっていますが、リストアイテムと背景とのコントラストを強めるために、ここでさらに追加してみましょう。すでに Card
shape
属性を使用してリストアイテムをシェーピングしました。次に、Card
elevation
属性を使用して、カードにエレベーションを追加します。エレベーションによって、基本的に Card
と背景とのコントラストがはっきりします。それによってシャドウが加わり、アプリがよりリアルに、また視覚的に魅力的に見えるようになります。
DogItem()
で、Card
のelevation
属性としてlist_item_elevation
を追加します。
Card(
modifier = Modifier.padding(8.dp),
elevation = 4.dp
)
- プレビューを更新します。エレベーションによって、アプリにシャドウと奥行きが生まれ、よりリアルに見えるようになります。
以下に、シェーピング前後のアプリを並べて示します。シェーピングを加えることで、アプリの魅力がどれだけ高まるかに注目してください。
シェーピングなし | シェーピングあり |
7. タイポグラフィを追加する
マテリアル デザインのタイプスケール
タイプスケールは、アプリ全体で使用できるフォント スタイルのセレクションです。柔軟でありながら一貫性のあるスタイルを保証します。マテリアル デザインのタイプスケールには、タイプシステムでサポートされる 13 のフォント スタイルが含まれています。この選択が必要になるのは、アプリをカスタマイズする場合のみです。タイプスケールのカテゴリ別の設定がわからない場合は、デフォルトのタイポグラフィ スケールを使用できます。
タイプスケールには、それぞれ意図された用途と意味を持つ、再利用可能なテキスト カテゴリが含まれています。このアプリでは、見出しと本文のカテゴリのみを使用します。
見出し
タイプスケールでは、見出しの範囲は 1~6 になります。見出しは画面で最大サイズのテキストであり、短く重要なテキストまたは数字用に予約されています。
本文
本文のテキストの範囲は 1~2 です。小さい文字にも対応するため、一般的に長いテキストに使用されます。
フォント
Android プラットフォームにはフォントがいくつか用意されていますが、デフォルトで用意されていないフォントを使用して、アプリを完全にカスタマイズしたい場合もあるかもしれません。カスタム フォントを使用すれば、個性を表現できます。ブランディングにも適しています。
このセクションでは、Abril Fatface、Montserrat Bold、Montserrat Regular というカスタム フォントを追加します。H1 見出しと H2 見出し、およびマテリアル タイプ システムの body1 テキストを使用して、アプリのテキストに追加します。
フォントの Android リソース ディレクトリを作成します。
アプリにフォントを追加する前に、フォントのディレクトリを作成する必要があります。
- Android Studio のプロジェクト ビューで、res フォルダを右クリックします。
- [New] > [Android Resource Directory] を選択します。
- ディレクトリの名前を「font」にして、[Resource type] を「font」に設定し、[OK] をクリックします。
- [res] > [font] にある新しいフォント リソース ディレクトリを開きます。
カスタム フォントをダウンロードする
Android プラットフォームでは提供されていないフォントを使用するため、カスタム フォントをダウンロードする必要があります。
- https://fonts.google.com/ にアクセスします。
- 「Montserrat」を検索して、[Download family] をクリックします。
- zip ファイルを解凍します。
- ダウンロードした Montserrat フォルダを開きます。static フォルダに Montserrat-Bold.ttf と Montserrat-Regular.ttf があります(ttf は、フォントのファイル形式である TrueType フォントの略です)。両方のフォントを選択し、Android Studio のプロジェクトのフォント リソース ディレクトリにドラッグします。
- フォント フォルダで、ファイル名 Montserrat-Bold.ttf を montserrat_bold.ttf に、Montserrat-Regular.ttf を montserrat_regular.ttf に変更します。
- 「Abril Fatface」を検索して [Download Family] をクリックします。
- ダウンロードした Abril_Fatface フォルダを開きます。AbrilFatface-Regular.ttf を選択し、フォント リソース ディレクトリにドラッグします。
- フォント フォルダで、ファイル名 Abril_Fatface.ttf を abril_fatface_regular.ttf に変更します。
3 つのカスタム フォント ファイルを追加したプロジェクトのフォント リソース ディレクトリは、次のようになります。
フォントを初期化する
- プロジェクト ウィンドウで ui.theme > Type.kt を開き、
Typography
変数の内容を削除します。
// Set of Material typography styles to start with
val Typography = Typography(
)
- インポート ステートメントの下、
Typography
val
の上にある、ダウンロードしたフォントを初期化します。まず、Abril Fatface をFontFamily
に設定して初期化し、フォント ファイルabril_fatface_regular
を指定してFont
を渡します。
val AbrilFatface = FontFamily(
Font(R.font.abril_fatface_regular)
)
- Abril Fatface の下にある Montserrat を
FontFamily
に設定して初期化し、フォント ファイルmontserrat_regular
を指定してFont
に渡します。montserrat_bold
についてはFontWeight.Bold
も指定します。太字のフォント ファイルを渡しても、Compose はファイルが太字であることを認識しないため、ファイルをFontWeight.Bold
に明示的にリンクする必要があります。
val AbrilFatface = FontFamily(
Font(R.font.abril_fatface_regular)
)
val Montserrat = FontFamily(
Font(R.font.montserrat_regular),
Font(R.font.montserrat_bold, FontWeight.Bold)
)
次に、先ほど追加したフォントにさまざまなタイプの見出しを設定します。Typography
オブジェクトには、前述の 13 種類の書体のパラメータがあります。これは必要な数だけ定義できます。このアプリでは、h1
(見出し 1)、h2
(見出し 2)、body1
を設定します。このアプリの次の部分では h3
(見出し 3)を使用するため、ここで追加します。
次に「アプリの概要」セクションの表を示します。追加する見出しごとにフォントとサイズが指定されています。
見出し | フォント | フォントの太さ | サイズ |
h1 | 標準 | 30 sp | |
h2 | 太字 | 20 sp | |
h3 | 太字 | 14 sp | |
body1 | 標準 | 14 sp |
- 上記の表を使用して、
Typography
val
に入力します。h1
属性にはTextStyle
を設定し、fontFamily
、fontWeight
、fontSize
に上記の表の情報を入力します。それにより、h1
に設定されたテキストのフォントはすべて通常の太さの Abril Fatface に設定され、fontSize
は30.sp
になります。
h2
、h3
、body1
についてもこの手順を繰り返します。
val Typography = Typography(
h1 = TextStyle(
fontFamily = AbrilFatface,
fontWeight = FontWeight.Normal,
fontSize = 30.sp
),
h2 = TextStyle(
fontFamily = Montserrat,
fontWeight = FontWeight.Bold,
fontSize = 20.sp
),
h3 = TextStyle(
fontFamily = Montserrat,
fontWeight = FontWeight.Bold,
fontSize = 14.sp
),
body1 = TextStyle(
fontFamily = Montserrat,
fontWeight = FontWeight.Normal,
fontSize = 14.sp
)
)
WoofTheme()
の Theme.kt ファイルに戻って MaterialTheme()
を見ると、typography
属性が、更新した Typography
val
に設定されていることがわかります。
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
アプリのテキストにタイポグラフィを追加する
次に、アプリの各テキスト インスタンスに見出しのタイプを追加します。
- 短く重要な情報である
h2
(見出し 2)をdog name
のスタイルとして追加します。小さい文字にも対応するbody1
をdog age
のスタイルとして追加します。
@Composable
fun DogInformation(@StringRes dogName: Int, dogAge: Int, modifier: Modifier = Modifier) {
Column {
Text(
text = stringResource(dogName),
style = MaterialTheme.typography.h2,
modifier = modifier.padding(top = 8.dp)
)
Text(
text = stringResource(R.string.years_old, dogAge),
style = MaterialTheme.typography.body1
)
}
}
- アプリを更新します。犬の名前は
20.sp
の太字の Montserrat フォントになり、犬の年齢は14.sp
の通常の Montserrat フォントになります。
以下に、タイポグラフィを追加した前後のアプリを並べて示します。犬の名前と犬の年齢のフォントの違いに注目してください。
タイポグラフィを使用しない場合 | タイポグラフィを使用した場合 |
8. トップバーを追加する
Scaffold
は、さまざまなコンポーネントや画面要素(Image
、Row
、Column
など)のためのスロットが用意されたレイアウトです。Scaffold
には、このセクションで使用する topBar
のためのスロットも用意されています。
topBar
はさまざまな用途に使用できますが、ここではブランディングとアプリの個性を出すために使用します。以下のスクリーンショットのようなコンポーザブルを作成し、Scaffold
の topBar
セクションに配置します。
このアプリのトップバーでは、ロゴとアプリのタイトルが行に表示されるようになっています。このロゴは、グラデーションが施されたかわいらしい足跡とアプリのタイトルで構成されています。
トップバーに画像とテキストを追加する
- MainActivity.kt で、
modifier
を受け入れるWoofTopAppBar()
というコンポーザブルを作成します。
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
}
WoofTopAppBar()
内にRow()
を追加します。
@Composable
fun WoofTopAppBar(modifier: Modifier = Modifier) {
Row() {
}
}
Row
にImage
を追加します。painter
を使用して、ドローアブル フォルダのImage
をic_woof_logo
に設定し、contentDescription
を null に設定します。このアプリロゴによって、視覚に障がいのあるユーザー向けのセマンティック情報は提供されないため、コンテンツの説明を追加する必要はありません。
Image(
painter = painterResource(R.drawable.ic_woof_logo),
contentDescription = null
)
- 次に、
Row
内のImage
の後にText
コンポーザブルを追加し、stringResource()
を使用してapp_name
の値に設定します。テキストにアプリの名前が設定されます。この名前はstrings.xml
に保存されています。
Text(
text = stringResource(R.string.app_name)
)
- アイコンとアプリ名を
TopAppBar()
に追加したので、TopAppBar()
をレイアウトに追加する必要があります。WoofApp()
で、LazyColumn
を囲むScaffold
を追加します。
import androidx.compose.material.Scaffold
@Composable
fun WoofApp() {
Scaffold(
) {
LazyColumn(modifier =
Modifier.background(MaterialTheme.colors.background)) {
items(dogs) {
DogItem(dog = it)
}
}
}
}
Scaffold
内にtopBar
属性を追加して、WoofTopAppBar()
に設定します。
Scaffold(
topBar = {
WoofTopAppBar()
}
)
WoofApp()
コンポーザブルは次のようになります。
@Composable
fun WoofApp() {
Scaffold(
topBar = {
WoofTopAppBar()
}
) {
LazyColumn(modifier = Modifier.background(MaterialTheme.colors.background)) {
items(dogs) {
DogItem(dog = it)
}
}
}
}
- プレビューを更新して、トップ アプリバーを確認します。アイコンとテキストが表示されていますが、完成品のようには見えません。次のセクションでは、色、タイポグラフィ、パディングなどを使用して、魅力的なデザインにします。
トップバーを美しく表示する
- まず、トップバーに背景色を追加して、アプリの他の部分と区別できるようにしましょう。
WoofTopAppBar()
で、Row
にmodifier
を追加することでアプリのメインテーマの色を背景色として追加し、背景色をprimary
に設定します。
Row(
modifier = modifier
.background(color = MaterialTheme.colors.primary)
){ }
- 背景色はアイコンとテキストの背後にのみ表示されますが、それをアプリ全体にわたって表示させたいとします。その場合は、
Row
のmodifier
をfillMaxWidth()
に設定します。
Row(
modifier = modifier
.fillMaxWidth()
.background(color = MaterialTheme.colors.primary)
){ }
- 次に、先に定義した
h1
(見出し 1)のスタイルに沿ってテキストを更新します。背景はprimary
色に設定されているため、テキストは自動的にonPrimary
色に設定されます。
Text(
text = stringResource(R.string.app_name),
style = MaterialTheme.typography.h1
)
- 見た目は大幅に良くなりますが、画像が小さすぎるため、周囲にパディングを施してみます。
Image
に修飾子を追加し、画像のサイズを64.dp
に設定し、画像の周囲のパディングを8.dp
に設定します。
Image(
modifier = Modifier
.size(64.dp)
.padding(8.dp),
painter = painterResource(R.drawable.ic_woof_logo),
contentDescription = null
)
- あと少しで完成です。次に、垂直方向の配置を
Alignment.CenterVertically
に設定します。それによって、行内のすべてのアイテムが垂直方向に中央揃えで配置されます。
import androidx.compose.ui.Alignment
Row(
modifier = modifier
.fillMaxWidth()
.background(color = MaterialTheme.colors.primary),
verticalAlignment = Alignment.CenterVertically
){ }
アプリを実行します。TopAppBar
によって、アプリが統一感を持った美しいデザインになったことを確認してください。
トップ アプリバーなし | トップ アプリバーあり |
次に、アプリをダークモードで実行します。バーには primary
色を使用し、テキストには onSurface
色を使用しているため、ダークモードに関する更新の必要はありません。
お疲れさまでした。これでこの Codelab は終了です。
9. (省略可)ステータスバーを変更する
時間、インターネット接続、バッテリーの状態などの情報を示すステータスバーの色を更新することで、ユーザー エクスペリエンスをさらに向上させることができます。
- [app] > [res] > [values] > [colors.xml] に移動します。
<resources>
タグの内容を削除します。
<resources>
</resources>
grey_50
を追加し、ライトモードのステータスバーを#FFF8F9FA
に設定し、grey_900
を追加して、ダークモードのステータスバーを#FF202124
に設定します。
<resources>
<color name="grey_50">#FFF8F9FA</color>
<color name="grey_900">#FF202124</color>
</resources>
- [app] > [res] > [values] > [themes.xml] に移動して、
android:statusBarColor
の色をgrey_50
に置き換えます。
<resources>
<style name="Theme.Woof" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:statusBarColor">@color/grey_50</item>
</style>
</resources>
- デバイスまたはエミュレータでアプリを実行します。
ステータスバーがトップ アプリバーとマッチして、カラーパターンは統一されましたが、アイコンが見づらくなってしまいました。
- themes.xml ファイルで、
windowLightStatusBar
をstatusBarColor
の下に追加し、true に設定します。
<resources>
<style name="Theme.Woof" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:statusBarColor">@color/grey_50</item>
<item name="android:windowLightStatusBar">true</item>
</style>
</resources>
- エラー メッセージが表示されます。メッセージにカーソルを合わせて、[Override Resources in values-v23] をタップします。
- これにより、v23/themes.xml という新しい themes.xml ファイルが作成されます。このファイルは API レベル 23 以上で使用します。
- エミュレータでアプリを実行します。アイコンが表示されます。
ダークモードでステータスバーを追加する
ダークモードでステータスバーをカスタマイズします。
- res フォルダに values-night という名前の新しい Android リソース ディレクトリを追加します。
- [Project Source Files] ファイルビューに切り替えます。
- [app] > [src] > [main] > [res] > [values-night] に移動します。
- values-night 内に、
themes.xml
という名前の値のリソース ファイルを追加します。 - 名前を
Theme.Woof
、親をandroid:style/Theme.Material.NoActionBar
としてスタイルタグを追加します。
<resources>
<style name="Theme.Woof" parent="android:style/Theme.Material.NoActionBar">
</style>
</resources>
- ステータスバーの色として
grey_900
を追加します。デフォルトのアイコンは白であるため、windowsStatusLightBar
を追加する必要はありません。
<resources>
<style name="Theme.Woof" parent="android:style/Theme.Material.NoActionBar">
<item name="android:statusBarColor">@color/grey_900</item>
</style>
</resources>
- ダークモードでアプリを実行して、ステータスバーが更新されたことを確認します。
10. 解答コードを取得する
この Codelab の完成したコードをダウンロードするには、以下の git コマンドを使用します。
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-woof.git $ cd basic-android-kotlin-compose-training-woof $ git checkout material
または、リポジトリを ZIP ファイルとしてダウンロードし、Android Studio で開くこともできます。
解答コードを確認する場合は、GitHub で表示します。
11. まとめ
今回は初めてのマテリアル アプリを作成しました。ライトモードとダークモード用のカスタム カラーパレットを追加し、さまざまなコンポーネントのシェイプを作成するとともに、フォントをダウンロードしてアプリに追加し、美しいトップバーを作成して全体を統合しました。この Codelab で習得したスキルを生かして、色、シェイプ、タイポグラフィを変更して、自分だけのアプリにカスタマイズしましょう。
概要
- マテリアル テーマ設定では、色、タイポグラフィ、シェイプのカスタマイズに関するガイダンスにより、アプリにマテリアル デザインを適用できます。
- Theme.kt ファイルはテーマを定義する場所です。このアプリの場合は、[アプリ名] +Theme() -
WoofTheme()
という名前のコンポーザブルを使用します。この関数内で、MaterialTheme
object
は、アプリのcolor
、typography
、shapes
、content
を設定します。 - アプリで使用する色は Colors.kt にリストされます。次に、Theme.kt で、特定のスロットに
LightColorPalette
とDarkColorPalette
の色を割り当てます。すべてのスロットに割り当てる必要はありません。 - アプリでフォースダークにオプトインすると、システムによってダークモードが実装されます。ただし、ダークモードの実装はユーザー エクスペリエンス向上に有効であるため、アプリのテーマについてはデベロッパーが完全に制御できます。
- Shapes.kt では、アプリのシェイプを定義します。シェイプには 3 つのサイズ(大、中、小)があり、角の丸みを指定できます。
- シェイプはユーザーの注意を引き、コンポーネントを明確に示し、状態を伝え、ブランドを表現するために役立ちます。
- Types.kt では、フォントを初期化し、マテリアル デザイン タイプのスケールに
fontFamily
、fontWeight
、fontSize
を割り当てます。 - マテリアル デザイン タイプのスケールには、アプリとそのコンテンツのニーズに対応する、多様で広範なスタイルが用意されています。タイプスケールは、タイプシステムでサポートされる 13 のスタイルを組み合わせたものです。