1. 始める前に
この Codelab では、Jetpack Compose を使用して、誕生日メッセージを画面上に表示するシンプルな Android アプリを作成します。
前提条件
- Android Studio でアプリを作成する方法。
- エミュレータまたは Android デバイスでアプリを実行する方法。
学習内容
- コンポーズ可能な関数(
Text
、Column
、Row
など)を記述する方法。 - アプリ内でテキストを表示する方法。
- テキストサイズやフォントサイズの変更など、テキストの書式を設定する方法。
作成するアプリの概要
- テキスト形式で誕生日祝いのメッセージを表示する Android アプリ。完成すると、以下のスクリーンショットのようになります。
必要なもの
- Android Studio がインストールされているパソコン
2. Code-Along 動画を見る(省略可)
コースの講師による Codelab の完了の様子を視聴される場合は、以下の動画を再生してください。
動画を拡大して全画面表示にすることをおすすめします(動画の右下隅にアイコン が表示されます)。これによって、Android Studio とコードがはっきりと表示されるようになります。
このステップは省略可能です。動画をスキップしてすぐに Codelab を開始することもできます。
3.Happy Birthday アプリを設定する
このタスクでは、Android Studio で Empty Compose Activity テンプレートを使用してプロジェクトを設定し、テキスト メッセージをカスタマイズされた誕生日祝いのメッセージに変更します。
Empty Compose Activity プロジェクトを作成する
- [Welcome to Android Studio] ダイアログで、[New Project] を選択します。
- [New Project] ダイアログで [Empty Compose Activity] を選択し、[Next] をクリックします。
- [Name] フィールドに「
Happy Birthday
」と入力し、[Minimum SDK] フィールドで API レベル 21 以上(Lollipop)を選択して、[Finish] をクリックします。
- Android Studio でプロジェクト ファイルが作成され、プロジェクトがビルドされるまで待ちます。
(Run 'app')をクリックします。
アプリは次のスクリーンショットのようになります。
この Happy Birthday アプリを Empty Compose Activity テンプレートで作成すると、基本的な Android アプリのリソースが設定され、画面に「Hello Android!」というメッセージが表示されます。この Codelab では、メッセージの配置方法、そのテキストを誕生日祝いのメッセージに変更する方法、さらにメッセージを追加して書式を設定する方法を説明します。
ユーザー インターフェース(UI)とは
アプリのユーザー インターフェース(UI)とは、画面上に表示されるテキスト、画像、ボタン、その他のさまざまな種類の要素と、これらの要素の画面での配置方法になります。アプリがユーザーに何かを表示する仕組み、ユーザーがアプリを操作する仕組みです。
以下の画像は、クリック可能なボタン、テキスト メッセージ、ユーザーがデータを入力できるテキスト入力フィールドです。
クリック可能なボタン
テキスト メッセージ
テキスト入力フィールド
これらの要素はそれぞれ UI コンポーネントと呼ばれます。アプリの画面に表示されるものは、ほぼすべてが UI 要素(UI コンポーネント)です。UI 要素は、クリック可能なボタンや編集可能な入力フィールドのようにインタラクティブなものにすることも、装飾的な画像にすることもできます。
この Codelab では、「Text
要素」というテキストを表示する UI 要素を使用します。
4. Jetpack Compose とは
Jetpack Compose は、Android UI を構築するための最新のツールキットです。Compose は、簡潔なコード、パワフルなツール、直感的な Kotlin 機能を使用して Android での UI の開発を簡素化し、加速します。Compose では、データを受け取って UI 要素を出力するコンポーズ可能な関数と呼ばれる一連の関数を定義することで、UI を構築できます。
コンポーズ可能な関数
コンポーズ可能な関数は、Compose の UI の基本的なビルディング ブロックです。コンポーズ可能な関数の機能は以下のとおりです。
- UI の一部を記述します。
- 何も返しません。
- 入力を受け取り、画面に表示されるものを生成します。
- 複数の UI 要素を出力する場合があります。
アノテーション
アノテーションは、コードに追加情報を付加する方法です。この情報は、Jetpack Compose コンパイラのようなツールや、他のデベロッパーがアプリのコードを理解する際に役立つものです。
アノテーションを付けるには、アノテーションを付ける宣言の先頭にある名前(アノテーション)の前に @
文字を追加します。アノテーションは、プロパティ、関数、クラスなど、さまざまなコード要素に付けることができます。クラスについてはコースの後半で学びます。
以下の図に、アノテーション付きの関数の例を示します。
次のコード スニペットは、アノテーション付きのプロパティの例を示しています。これらのサンプルは、この Codelab の後半で使用します。
// Example code, do not copy it over
@Json
val imgSrcUrl: String
@Volatile
private var INSTANCE: AppDatabase? = null
パラメータ付きアノテーション
アノテーションはパラメータを受け入れることができます。これらのパラメータは、それらを処理するツールに追加情報を提供します。パラメータがある場合とない場合の @preview
アノテーションの例を以下に示します。
パラメータなしのアノテーション
背景をプレビューするアノテーション
プレビュー タイトル付きのアノテーション
以下に示すように、アノテーションに複数のパラメータを渡すことができます。
プレビュー タイトルとシステム UI 付きのアノテーション(スマートフォンの画面)
Jetpack Compose にはさまざまな組み込みアノテーションが用意されています。これまでのコースで、@Composable
アノテーションと @Preview
アノテーションについて説明しました。コースの後半では、さらに多くのアノテーションとその使用方法を学びます。
コンポーズ可能な関数の例
コンポーズ可能な関数には、@Composable
アノテーションが付けられています。コンポーズ可能な関数はすべて、このアノテーションが必要です。このアノテーションは、この関数がデータを UI に変換するためのものであることを Compose コンパイラに伝えます。なお、コンパイラとは、記述したコードを 1 行ずつ読み、コンピュータが理解できる内容(機械語)に変換する特殊なプログラムです。
このコード スニペットは、シンプルなコンポーズ可能な関数の例です。渡されるデータ(name
関数パラメータ)を使用して、画面上にテキスト要素をレンダリングしています。
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
コンポーズ可能な関数には以下の特徴があります。
- コンポーズ可能な関数は、アプリのロジックで UI の記述や変更を行えるようにするパラメータを受け入れることができます。今回の例では、UI 要素で
String
を受け入れることで、名前を入れてユーザーにメッセージを表示できます。 - 関数から何も返しません。UI を出力するコンポーズ可能な関数は、UI 要素を作成するのではなく目的の画面状態を記述するため、何かを返す必要はありません。つまり、コンポーズ可能な関数は UI を記述するだけで UI の構築も作成も行わないため、何も返しません。
コード内でのコンポーズ可能な関数について
- Android Studio で
MainActivity.kt
ファイルを開きます。 DefaultPreview()
関数までスクロールして、この関数を削除します。以下に示すように、Greeting()
関数をプレビューするためのコンポーズ可能な関数BirthdayCardPreview()
を新たに追加します。関数には、その機能を説明する名前を付けるか、そのような名前に変更することをおすすめします。
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
BirthdayCardTheme {
Greeting("Android")
}
}
コンポーズ可能な関数は、他のコンポーズ可能な関数を呼び出すことができます。上記のコード スニペットでは、Preview 関数でコンポーズ可能な関数 Greeting()
を呼び出しています。
なお、元の関数には、@Composable
アノテーションの前にパラメータが付いた別のアノテーション @Preview
もありました。Preview
アノテーションに渡される引数については、このコースの後半で詳しく説明します。
コンポーズ可能な関数の名前
Compose 関数が何も返さず、@Composable
アノテーションが付いている場合は、パスカルケースを使用して名前を付ける必要があります。パスカルケースとは、複合語内の各単語の最初の文字が大文字になる命名規則を指します。パスカルケースとキャメルケースの違いは、パスカルケースでは、すべての単語の最初の文字が大文字になることです。キャメルケースでは、最初の文字が大文字にはなりません。
Compose 関数:
- 必ず名詞にしてください:
DoneButton()
- 動詞または動詞句にしないでください:
DrawTextField()
- 名詞の前置詞にしないでください:
TextFieldWithLink()
- 形容詞にしないでください:
Bright()
- 副詞にしないでください:
Outside()
- 名詞の前に記述形容詞を付けることができます:
RoundIcon()
このガイドラインは、関数が UI 要素を出力するかどうかにかかわらず適用されます。詳しくは、コンポーズ可能な関数の命名をご覧ください。
サンプルコード。コピーしないでください
// Do: This function is a descriptive PascalCased noun as a visual UI element
@Composable
fun FancyButton(text: String) {
// Do: This function is a descriptive PascalCased noun as a non-visual element
// with presence in the composition
@Composable
fun BackButtonHandler() {
// Don't: This function is a noun but is not PascalCased!
@Composable
fun fancyButton(text: String) {
// Don't: This function is PascalCased but is not a noun!
@Composable
fun RenderFancyButton(text: String) {
// Don't: This function is neither PascalCased nor a noun!
@Composable
fun drawProfileImage(image: ImageAsset) {
5. Android Studio のデザインペイン
Android Studio では、アプリを Android デバイスまたはエミュレータにインストールしなくても、コンポーズ可能な関数を IDE 内でプレビューできます。前のパスウェイで学習したように、Android Studio の [Design] ペインでアプリの外観をプレビューできます。
コンポーズ可能な関数は、プレビューするすべてのパラメータのデフォルト値を指定する必要があります。このため、Greeting()
関数を直接プレビューすることはできません。代わりに、別の関数(この場合は BirthdayCardPreview()
関数)を追加します。この関数は、適切なパラメータで Greeting()
関数を呼び出します。
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview() {
BirthdayCardTheme {
Greeting("Android")
}
}
Preview
アノテーションの showBackground
パラメータについては、後半の Codelab で説明します。
プレビューを表示するには:
- コードをビルドする
プレビューが自動的に更新されます。
プレビューをアップデートまたは更新するもう 1 つの方法は、[Design] ペインで [Build & Refresh] をクリックすることです。
BirthdayCardPreview()
関数で、Greeting()
関数の「Android"
」引数を自分の名前に置き換えます。
fun BirthdayCardPreview() {
BirthdayCardTheme {
Greeting("James")
}
}
- [Design] ペインで
[Build & Refresh] をクリックします。
更新されたプレビューが表示されます。
6. 新しいテキスト要素を追加する
このタスクでは、Hello Android!
のメッセージを削除して誕生日祝いのメッセージを追加します。
新しいコンポーズ可能な関数を追加する
MainActivity.kt
ファイルで、Greeting()
関数の定義を削除します。この Codelab の後半で、独自に作成した関数を追加して誕生日祝いのメッセージを表示します。
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
- Android Studio は
Greeting()
関数呼び出しをハイライト表示します。この関数呼び出しにカーソルを合わせると、エラーを特定できます。
Greeting()
関数呼び出しとその引数をonCreate()
関数とBirthdayCardPreview()
関数から削除します。MainActivity.kt
ファイルは次のようになります。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BirthdayCardTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun BirthdayCardPreview(){
BirthdayCardTheme {
}
}
BirthdayCardPreview()
関数の前に、BirthdayGreetingWithText()
という新しい関数を追加します。この関数の前に@Composable
アノテーションを追加するようにしてください。これは、Text
コンポーザブルを出力する Compose 関数になります。
@Composable
fun BirthdayGreetingWithText() {
}
String
型のmessage
パラメータをコンポーズ可能な関数BirthdayGreetingWithText()
に追加します。
@Composable
fun BirthdayGreetingWithText(message: String) {
}
BirthdayGreetingWithText()
関数にText()
コンポーザブルを追加し、テキスト メッセージを名前付き引数として渡します。
@Composable
fun BirthdayGreetingWithText(message: String) {
Text(
text = message
)
}
この BirthdayGreetingWithText()
関数は UI にテキストを表示します。そのために、コンポーズ可能な関数 Text()
を呼び出します。
関数をプレビューする
このタスクでは、[Design] ペインで BirthdayGreetingWithText()
関数をプレビューします。
BirthdayCardPreview()
関数内でBirthdayGreetingWithText()
関数を呼び出します。String
引数(友人への誕生日祝いのメッセージ)をBirthdayGreetingWithText()
関数に渡します。必要に応じて、"Happy Birthday Sam!"
などの名前でカスタマイズできます。
@Preview(showBackground = false)
@Composable
fun BirthdayCardPreview() {
BirthdayCardTheme {
BirthdayGreetingWithText( "Happy Birthday Sam!")
}
}
- [Design] ペインで、
[Build & Refresh] をクリックし、ビルドが完了するまで待って関数をプレビューします。
7. フォントサイズを変更する
ユーザー インターフェースにテキストを追加しましたが、まだ最終版のアプリとは外観に違いがあります。このタスクでは、テキスト要素の外観に影響を与えるサイズ、テキストの色などの属性を変更する方法を学びます。さまざまなフォントサイズと色も試します。
拡張可能ピクセル
拡張可能ピクセル(SP)はフォントサイズの単位です。Android アプリの UI 要素では、2 種類の測定単位を使用します。1 つは後でレイアウトに使用する密度非依存ピクセル(DP)で、もう 1 つは拡張可能ピクセル(SP)です。SP の単位は、デフォルトでは DP の単位と同じですが、ユーザーがスマートフォン設定で選択するテキストサイズに基づいて変更されます。
MainActivity.kt
ファイルで、BirthdayGreetingWithText()
関数内のText()
コンポーザブルまでスクロールします。fontSize
引数を 2 つ目の名前付き引数としてText()
関数に渡し、その値を36.
sp
に設定します。
Text(
text = message,
fontSize = 36.sp
)
アプリをコンパイルするにはクラスまたはプロパティをいくつかインポートする必要があり、Android Studio は .sp
コードをハイライト表示します。
- Android Studio でハイライト表示されている
.sp
をクリックします。 - ポップアップで [Import] をクリックし、
androidx.compose.ui.unit.sp
をインポートして.sp
拡張プロパティを使用します。
- ファイルの先頭までスクロールすると、
import
ステートメントが表示されます。Android Studio によってパッケージがファイルに追加されたことを示すimport androidx.compose.ui.unit.sp
ステートメントがここに表示されています。
- [Design] ペインで [Build & Refresh] をクリックして、更新されたプレビューを表示します。メッセージのプレビューでフォントサイズが変更されていることがわかります。
さまざまなフォントサイズを試すことができるようになりました。
8. 別のテキスト要素を追加する
前のタスクでは、友人への誕生日祝いのメッセージを追加しました。このタスクでは、カードに自分の名前で署名します。
MainActivity.kt
ファイルで、BirthdayGreetingWithText()
関数までスクロールします。- 署名用に、
String
型のfrom
パラメータを関数に渡します。
fun BirthdayGreetingWithText(message: String, from: String)
- 誕生日のメッセージ
Text
コンポーザブルの後に、from
値に設定されたtext
引数を受け入れる別のText
コンポーザブルを追加します。
Text(
text = from
)
fontSize
名前付き引数を追加し、その値を24.sp
に設定します。
Text(
text = from,
fontSize = 24.sp
)
BirthdayCardPreview()
関数までスクロールします。- カードに署名を入れる(
"- from Emma"
など)ために、別のString
引数を追加します。
BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
- [Design] ペインで [Build & Refresh] をクリックします。
- プレビューが表示されます。
コンポーズ可能な関数は、複数の UI 要素を出力することがあります。ただし、配置方法のガイダンスが提供されないと、Compose は望ましくない方法で要素を配置する可能性があります。たとえば、前のコードでは、2 つのコンポーザブルの配置方法に関するガイダンスがないため、2 つのテキスト要素が互いに重なり合って生成されます。
次のタスクでは、コンポーザブルを行または列の形式で配置する方法を学習します。
9. 行または列内のテキスト要素を配置する
UI 階層
UI 階層は包含を基本としています。つまり、1 つのコンポーネントに 1 つ以上のコンポーネントを含めることができ、「親」と「子」という用語が使用されることもあります。この場合、親 UI 要素が子 UI 要素を含み、その子 UI 要素がさらに子 UI 要素を含むことができます。このセクションでは、親 UI 要素として機能できる Column、Row、Box のコンポーザブルについて学習します。
Compose には基本となる標準レイアウト要素として、Column
、Row
、Box
の 3 つのコンポーザブルがあります。Box
コンポーザブルについては、次の Codelab で詳しく説明します。
Column
、Row
、Box
は、コンポーズ可能なコンテンツを引数として受け取るコンポーズ可能な関数であり、これらのレイアウト要素内にアイテムを配置できます。たとえば、Row
コンポーザブル内の子要素は、それぞれ横方向に並べて配置されます。
// Don't copy.
Row {
Text("First column")
Text("Second column")
}
これらのテキスト要素は、次の画像のように画面上に並んで表示されます。
青い枠線はわかりやすく示すためのものであり、実際には表示されません。
後置ラムダ構文
前のコード スニペットでは、コンポーズ可能な関数 Row
で、かっこの代わりに中かっこが使用されています。これを後置ラムダ構文と呼びます。ラムダと後置ラムダ構文については、このコースの後半で詳しく説明します。ここでは、一般的に使用される Compose 構文の使い方を学びます。
Kotlin には、最後のパラメータが関数の場合に、関数をパラメータとして渡すための特別な構文が用意されています。
パラメータとして関数を渡す場合は、後置ラムダ構文を使用できます。関数を関数名とともにかっこで囲むのではなく、関数名の後にかっこを配置します。これは Compose ではよくあることであるため、コードの見た目に慣れておく必要があります。
たとえば、コンポーズ可能な関数 Row()
の最後のパラメータは content
パラメータです。これは子 UI 要素を出力する関数です。3 つのテキスト要素を含む行を作成する場合、このコードは機能しますが、非常に面倒です。
Row(
content = {
Text("Some text")
Text("Some more text")
Text("Last text")
}
)
content
パラメータは、署名用の関数の最後のパラメータであり、値をラムダ式として渡します(今のところ、ラムダが何であるかがわからなくてもかまいません。構文に慣れてください)。このため、次のように content
パラメータとかっこを削除できます。
Row {
Text("Some text")
Text("Some more text")
Text("Last text")
}
テキスト要素を行に配置する
このタスクでは、重複を避けるため、アプリのテキスト要素を行に配置します。
MainActivity.kt
ファイルで、BirthdayGreetingWithText()
関数までスクロールします。- テキスト要素の周囲に
Row
コンポーザブルを追加して、2 つのテキスト要素を含む列を表示します。
この関数は次のコード スニペットのようになります。
@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
Row{
Text(
text = message,
fontSize = 36.sp,
)
Text(
text = from,
fontSize = 24.sp,
)
}
}
- コード スニペットのハイライト表示されているところで
Row
をクリックします。 - なお、Android Studio には
Row
のインポート オプションが複数用意されています。 - [Import] をクリックします。
Row(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.Argument.Horizontal, androidx
....
で始まるandroidx.compose.ui
クラスからパッケージを選択します。
- [Build & Refresh] をクリックして、[Design] ペインでプレビューを更新します。
重複がなくなり、プレビューが見やすくなります。しかし、署名のための十分なスペースがないため、これは望ましくありません。次のタスクでは、テキスト要素を列に配置して、この問題を解決します。
テキスト要素を列で配置する
このタスクでは、BirthdayGreetingWithText()
関数を変更して、テキスト要素を列に配置します。必ず [Build & Refresh] をクリックしてプレビューを更新してください。画面のスクリーンショットは次のようになります。
各自で演習を行ったので、以下のスニペット内の解答コードとご自身のコードを確認してみてください。
@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
Column {
Text(
text = message,
fontSize = 36.sp,
)
Text(
text = from,
fontSize = 24.sp,
)
}
}
Android Studio のプロンプトが表示されたら、以下のパッケージをインポートします。
import androidx.compose.foundation.layout.Column
10. デバイスでの表示
プレビューを確認したら、デバイスまたはエミュレータでアプリを実行します。
MainActivity.kt
ファイルで、onCreate()
関数までスクロールします。Surface
ブロックからBirthdayGreetingWithText()
関数を呼び出します。BirthdayGreetingWithText()
関数(誕生日祝いのメッセージと署名)を渡します。
完成した onCreate()
関数は次のコード スニペットのようになります。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
BirthdayCardTheme {
// A surface container that uses the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
}
}
}
}
}
- エミュレータ上でアプリをビルドして実行します。
11. 解答コードを取得する
完成した MainActivity.kt
:
package com.example.android.happybirthday
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import com.example.happybirthday.ui.theme.HappyBirthdayTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HappyBirthdayTheme {
// A surface container that uses the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
}
}
}
}
}
@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
Column {
Text(
text = message,
fontSize = 36.sp,
)
Text(
text = from,
fontSize = 24.sp,
)
}
}
@Preview(showBackground = false)
@Composable
fun BirthdayCardPreview() {
HappyBirthdayTheme {
BirthdayGreetingWithText( "Happy Birthday Sam!", "- from Emma")
}
}
12. おわりに
Happy Birthday アプリを作成しました。
次の Codelab では、アプリに画像を追加し、テキスト要素の配置を変更してアプリの見た目を整えます。
概要
- Jetpack Compose は、Android UI を構築するための最新のツールキットです。Jetpack Compose は、簡潔なコード、パワフルなツール、直感的な Kotlin API により、Android での UI 開発を簡素化し、加速します。
- アプリのユーザー インターフェース(UI)は、画面上に表示されるテキスト、画像、ボタン、その他のさまざまな種類の要素です。
- コンポーズ可能な関数は、Compose の基本的なビルディング ブロックです。コンポーズ可能な関数とは、UI の一部を記述する関数のことです。
- コンポーズ可能な関数には、
@Composable
アノテーションが付けられます。このアノテーションは、この関数がデータを UI に変換するためのものであることを Compose コンパイラに伝えます。 - Compose には基本的となる標準レイアウト要素として、
Column
、Row
、Box
の 3 つのコンポーザブルがあります。これらのコンポーザブルは、コンポーズ可能なコンテンツを受け取るコンポーズ可能な関数であり、内部にアイテムを配置できます。たとえば、Row
内のそれぞれの子が横に並べて配置されます。