今回と次回は、Jetpack ComposeでHello Worldに挑戦します。まず今回は、Android StudioのJetpack Compose用プロジェクトテンプレートを使って、とにかくJetpack Composeを動かしてみます。しかし、テンプレートを使うと、必要な設定などが自動で行われる一方、不要なものまで勝手に追加されていたりして、純粋にJetpack Composeを動かすために何が必要なのかが見えづらい部分がありますので、次回は、必要な設定を自分で追加して動かしてみます。
プロジェクト作成
まずはテンプレートを選択してプロジェクトを作成します。
File
> New
> New Project
をクリックします。
Empty Compose Activity
を選択し、Next
をクリックします。
プロジェクト名などを入力し、Finish
をクリックします。
ビルドして実行
このプロジェクトテンプレートは、作成したそのままでビルドが通るように準備されています。ソースコードは一切手を加えず、さっそくビルドして実行してみましょう。”Hello Android!”と表示されるのを確認できます。文字小さいですね(笑) このテンプレートではテーマが有効になっているので、ダークモードのON/OFFで色が変わります。
ソースコード確認
ここからは MainActivity.kt
のソースコードを見ながら、実際に何をやっているのかを確認していきます。
MainActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HelloCompose1Theme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
}
}
}
MainActivity
は、AppCompatActivity
ではなくComponentActivity
のサブクラスになっています。AppCompatActivity
はComponentActivity
のサブクラスです。継承関係は図のようになっています。ComponentActivity
にFragmentの管理機能などを加えたものがFragmentActivity
で、それに更にActionBarなどの機能を加えたものがAppCompatActivity
です。Jetpack Composeでは基本的にFragmentは使わないので、基底クラスのComponentActivity
が使われているのだと思われます。
onCreate()
では、setContentView()
ではなくsetContent()
を呼び出しています。setContent()
はandroidx.activity.compose
パッケージに定義されている(つまりJetpack Compose対応として追加された)、ComponentActivity
の拡張関数です。引数に与えたComposableにより作成されるUIを、ActivityのルートViewとして設定します。ここで出てきた”Composable”とは、Jetpack Composeの仕組みによりUIを作成する関数のことです。Jetpack ComposeではComposableな関数を入れ子で呼び出すことにより、UIの階層を宣言します。setContent()
の引数に与えるComposableが、UI階層のルートになります。
ちなみに、setContent
には”( )”がなくて”{ }”がついていますが、これはKotlinの記法によるもので、関数の最後のラムダ引数が( )の外側に出され、それにより( )内の引数がなくなったので( )自体が省略された状態です。つまりsetContent{ ... }
はComposable関数のラムダ式をsetContent
の引数として与えていることを意味しています。Jetpack Composeではこの書き方が多用されますので、慣れていきましょう。
HelloCompose1Theme()
はプロジェクトテンプレートにより自動作成されるComposableで、Theme.kt
に定義されています。詳しくはテーマについて説明する回で見ていきますが、このComposableで、ライトテーマとダークテーマの設定をしており、これより下の階層でMaterialTheme.colors
から呼び出す色を指定しています。
Surface()
はJetpack Composeでマテリアルデザインを実現するための基本ウィジェットです。当然これもComposableです。ここではcolor
引数にMaterialTheme.colors.background
を指定しているので、HelloCompose1Theme()
の中で指定したアプリのテーマの背景色が適用されます。Jetpack Composeで背景色を指定するには、個別のウィジェットにbackgroundを設定するのではなく、Surface
のcolorを設定するのがよいとされています。
注: 要素の背景色を設定する際は、
https://developer.android.com/jetpack/compose/themes?hl=ja#content-colorSurface
を使用することをおすすめします。Surface
は適切なコンテンツ色を設定します。Modifier.background()
で直接呼び出すと適切なコンテンツ色が設定されないため、ご注意ください。
やっとGreeting()
までたどり着きました。Greeting()
が、”Hello Android!”という文字列を表示しているComposableです。次はGreeting()
の実装を見ていきます。
Composableの実装
このサンプルのUI本体の実装は、Greeting()
のみです。Greeting()
はMainActivity.kt
のファイル内に定義されていますが、MainActivity
クラスの外、トップレベル関数として定義されています。
Greeting()
は、引数として受け取った文字列に”Hello”をつけて画面に表示するようになっています。Text()
は、text
引数に指定した文字列を表示するComposableです。従来のViewシステムではTextViewに相当するUIウィジェットになりますが、Jetpack ComposeはViewとは別物なので、Text ComposableはTextViewとは全くの別物になります。Jetpack Composeでは、Composableを呼び出す関数もComposableである必要があります。したがって、Text()
を呼び出しているGreeting()
もComposableである必要があるので、@Composable
アノテーションがついています。
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
HelloCompose1アプリとしてのMainActivity
の実装は以上です。しかし、MainActivity.kt
にはあと一つ、関数が実装されています。
Preview
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
HelloCompose1Theme {
Greeting("Android")
}
}
@Preview
アノテーションがついたComposable関数は、Android Studioの画面上でプレビューを表示するための関数です。MainActivity
タブの右上のSplit
をクリックすると、DefaultPreview()
のプレビューが表示されます。showBackground = true
を指定することで、プレビューの背景が白になっています。この白色は、HelloCompose1Theme()
で定義しているアプリのテーマとは無関係です。Greeting()
の中ではMaterialTheme
を利用していないので、HelloCompose1Theme()
は特に何も仕事をしていません。このプロジェクトテンプレートの中でも紛らわしい部分だと思います。
まとめ
以上で、Empty Compose Activityテンプレートを使ったHello Worldは完了です。テンプレートをそのまま実行し、テキストが表示されることを確認しました。また、テーマが適用されていることも確認しました。ソースコードは、MainActivity.kt
を中心に確認しました。
まだ確認できていないこととしては、Gradleの設定などがあります。この辺りは次回、手動で一つ一つ設定を行いながら見ていきたいと思います。