Jetpack Compose入門(3) Hello World! テンプレート利用編
今回と次回は、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で色が変わります。

ダークモードOFF

ダークモードON
ソースコード確認
ここからは 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を設定するのがよいとされています。
注: 要素の背景色を設定する際は、
Surfaceを使用することをおすすめします。Surfaceは適切なコンテンツ色を設定します。Modifier.background()で直接呼び出すと適切なコンテンツ色が設定されないため、ご注意ください。https://developer.android.com/jetpack/compose/themes?hl=ja#content-color
やっと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アノテーションがついています。
@Composablefun Greeting(name: String) { Text(text = "Hello $name!")}HelloCompose1アプリとしてのMainActivityの実装は以上です。しかし、MainActivity.ktにはあと一つ、関数が実装されています。
Preview
@Preview(showBackground = true)@Composablefun 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の設定などがあります。この辺りは次回、手動で一つ一つ設定を行いながら見ていきたいと思います。
