レッスン 1: コンポーズ可能な関数
Jetpack Compose は、コンポーズ可能な関数に基づいて構築されています。コンポーズ可能な関数を使用すると、UI の外観とデータの依存関係を指定することにより、アプリの UI をプログラムで定義できます。UI の構築プロセス(要素の初期化や親へのアタッチなど)に注意を払う必要はありません。コンポーズ可能な関数は、関数名に @Composable アノテーションを追加するだけで作成できます。
テキスト要素を追加する
最初に、の最新版をダウンロードしてください。 Android Studio でアプリを作成し、[New Project] を選択してアプリを作成し、 [Phone and Tablet] カテゴリで、[Empty Activity] を選択します。 アプリに「ComposeTutorial」という名前を付け、[Finish] をクリックします。デフォルト テンプレートにはすでにいくつかの Compose 要素が含まれていますが、このチュートリアルでは段階的に要素を作成します。
まず、onCreate メソッド内にテキスト要素を追加して、「Hello world!」というテキストを表示します。そのためには、content ブロックを定義し、コンポーズ可能な関数 Text を呼び出します。setContent ブロックでは、コンポーズ可能な関数が呼び出されるアクティビティのレイアウトを定義します。コンポーズ可能な関数は、他のコンポーズ可能な関数からのみ呼び出すことができます。
Jetpack Compose は、Kotlin コンパイラ プラグインを使用して、これらのコンポーズ可能な関数をアプリの UI 要素に変換します。たとえば、Compose UI ライブラリで定義されているコンポーズ可能な関数 Text は、画面上にテキストラベルを表示します。
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material3.Text class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text("Hello world!") } } }
コンポーズ可能な関数を定義する
関数をコンポーズ可能にするには、@Composable アノテーションを追加します。これを試すには、名前を受け取り、その名前を使用してテキスト要素を構成する MessageCard 関数を定義します。
// ... import androidx.compose.runtime.Composable class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MessageCard("Android") } } } @Composable fun MessageCard(name: String) { Text(text = "Hello $name!") }
Android Studio で関数をプレビューする
@Preview アノテーションを使用すると、アプリをビルドして Android デバイスまたはエミュレータにインストールしなくても、Android Studio 内でコンポーズ可能な関数をプレビューできます。アノテーションは、パラメータを受け取らないコンポーズ可能な関数で使用する必要があります。したがって、MessageCard 関数を直接プレビューすることはできません。代わりに、PreviewMessageCard という 2 番目の関数を作成します。この関数は、適切なパラメータで MessageCard を呼び出します。@Composable の前に @Preview アノテーションを追加します。
// ... import androidx.compose.ui.tooling.preview.Preview @Composable fun MessageCard(name: String) { Text(text = "Hello $name!") } @Preview @Composable fun PreviewMessageCard() { MessageCard("Android") }
プロジェクトを再ビルドします。新しい PreviewMessageCard 関数はどこからも呼び出されないのでアプリ自体に変更はありませんが、分割(デザイン / コード)ビューをクリックすると展開できるプレビュー ウィンドウが Android Studio に追加されます。このウィンドウには、@Preview アノテーションが付いているコンポーズ可能な関数によって作成された UI 要素のプレビューが表示されます。プレビュー ウィンドウの上部にある更新ボタンをクリックすると、プレビューを随時更新できます。
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material3.Text class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Text("Hello world!") } } }
// ... import androidx.compose.runtime.Composable class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MessageCard("Android") } } } @Composable fun MessageCard(name: String) { Text(text = "Hello $name!") }
// ... import androidx.compose.ui.tooling.preview.Preview @Composable fun MessageCard(name: String) { Text(text = "Hello $name!") } @Preview @Composable fun PreviewMessageCard() { MessageCard("Android") }
複数のテキストを追加する
ここまでの作業で、最初のコンポーズ可能な関数とプレビューを作成しました。次は、Jetpack Compose のその他の機能を確認するため、アニメーションで展開できるメッセージのリストを表示するシンプルなメッセージ画面を作成します。
手始めに、メッセージのコンポーザブルをより充実させるために、作成者の名前とメッセージ コンテンツを表示します。まず、String の代わりに Message オブジェクトを受け入れるようにコンポーザブルのパラメータを変更し、MessageCard コンポーザブル内にもう一つの Text コンポーザブルを追加します。プレビューも必ず更新してください。
// ... class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MessageCard(Message("Android", "Jetpack Compose")) } } } data class Message(val author: String, val body: String) @Composable fun MessageCard(msg: Message) { Text(text = msg.author) Text(text = msg.body) } @Preview @Composable fun PreviewMessageCard() { MessageCard( msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!") ) }
このコードは、コンテンツ ビュー内に 2 つのテキスト要素を作成します。しかし、テキスト要素をどう配置するかに関する情報を指定していないので、それらは重なって描画され、テキストを判読できません。
画像要素を追加する
メッセージ カードをもっと充実させるために、送信者のプロフィール写真を追加しましょう。リソース マネージャー を使ってフォト ライブラリから画像をインポートするか、こちらの画像を使用します。適切に構造化設計され、内部に Image コンポーザブルを含んでいる Row コンポーザブルを追加します。
// ... import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Row import androidx.compose.ui.res.painterResource @Composable fun MessageCard(msg: Message) { Row { Image( painter = painterResource(R.drawable.profile_picture), contentDescription = "Contact profile picture", ) Column { Text(text = msg.author) Text(text = msg.body) } } }
レイアウトを構成する
メッセージ レイアウトの構造は適切ですが、要素が適切に配置されておらず、画像が大きすぎます。コンポーザブルを装飾または構成するため、Compose は修飾子を使用します。修飾子により、コンポーザブルのサイズ、レイアウト、外観を変更したり、高度なインタラクション(要素をクリック可能にするなど)を追加したりできます。修飾子を連結すると、より充実したコンポーザブルを作成できます。修飾子をいくつか使用してレイアウトを改善します。
// ... import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp @Composable fun MessageCard(msg: Message) { // Add padding around our message Row(modifier = Modifier.padding(all = 8.dp)) { Image( painter = painterResource(R.drawable.profile_picture), contentDescription = "Contact profile picture", modifier = Modifier // Set image size to 40 dp .size(40.dp) // Clip image to be shaped as a circle .clip(CircleShape) ) // Add a horizontal space between the image and the column Spacer(modifier = Modifier.width(8.dp)) Column { Text(text = msg.author) // Add a vertical space between the author and message texts Spacer(modifier = Modifier.height(4.dp)) Text(text = msg.body) } } }
// ... class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MessageCard(Message("Android", "Jetpack Compose")) } } } data class Message(val author: String, val body: String) @Composable fun MessageCard(msg: Message) { Text(text = msg.author) Text(text = msg.body) } @Preview @Composable fun PreviewMessageCard