5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Jetpack Composeを学ぶ ComposeTutorial

Last updated at Posted at 2023-03-23

はじめに

JetpackComposeチュートリアルを学んだ内容を記載してます
(一応第0回の続き)

レッスン1 コンポーズ可能な関数

コンポーズ可能な関数とは

  • @Composableアノテーションを付けることで宣言可能
  • UIの外観とデータの依存関係を指定することによってアプリのUIをプログラムで定義できる関数
  • 要素の初期化や親のViewへのアタッチなどを気にしなくて済む

テキスト追加

  • setContentブロックでコンポーズ可能な関数が呼び出されるアクティビティのレイアウトを定義
  • Textは画面上にテキストラベルを表示
.kt
setContent {
    Text("Hello world!")
}

コンポーズ可能な関数を定義

@Composableアノテーションを追加することで関数をコンポーズ可能にできる

.kt
@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

AndroidStudioでプレビュー

  • @Previewアノテーションを付けることでAndroidデバイスやエミュレータにインストールせずに確認できる
  • @Previewアノテーションはパラメータを受け取らないコンポーズ可能な関数にのみ使用することができる
.kt
@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard("Android")
}

レッスン2 レイアウト

  • Composeで定義していくUIは階層状
  • コンポーズ可能な関数からコンポーズ可能な関数を呼び出していくことで様々なUIを表現可能

複数テキストの定義

.kt
data class Message(val author: String, val body: String)

@Composable
fun MessageCard(msg: Message) {
    Text(text = msg.author)
    Text(text = msg.body)
}

列を使用する

  • Column関数で要素を垂直方向に揃えることができる
  • Row関数は水平方向
  • Box関数で要素を積み重ねられる
.kt
@Composable
fun MessageCard(msg: Message) {
    Column {
        Text(text = msg.author)
        Text(text = msg.body)
    }
}

画像要素を追加

  • Image関数で画像リソースを追加
  • contentDescriptionも設定可能
.kt
Image(
    painter = painterResource(R.drawable.profile_picture),
    contentDescription = "Contact profile picture",
)

レイアウトを構成

  • Modifier関数

    • コンポーザブルのサイズ、レイアウト、外観の変更
      • padding,widh,height
      • clip,borderなど
    • クリック可能などのインタラクションを追加
      • clickableなど
.kt
Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
            modifier = Modifier
                // 画像サイズ設定
                .size(40.dp)
                // 丸で型取り
                .clip(CircleShape)
        )

        // 要素同士横方向のスペース設定
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(text = msg.author)
            // テキスト縦方向のスペース設定
            Spacer(modifier = Modifier.height(4.dp))
            Text(text = msg.body)
        }
    }

レッスン3 マテリアルデザイン

Composeはマテリアルデザインの原則をサポート
UI要素の多くは最初からマテリアルデザインを実装

マテリアルデザインの使用

  • プロジェクトの名前+Theme(例:ComposeTutorialTheme)とSurface関数でをコンポーズ可能な関数をラップ
  • マテリアルデザインはColor, Typography, Shapeを中心に構成
.kt
setContent {
    ComposeTutorialTheme {
        Surface(modifier = Modifier.fillMaxSize()) {
            MessageCard(Message("Android", "Jetpack Compose"))
        }
    }
}

Color

  • MaterialTheme.Colorsを使用
  • 必要な場合どこでもテーマの値を使用可能
.kt
modifier = Modifier
    .size(40.dp)
    .clip(CircleShape)
    // 枠線を描画し、カラー適用
    .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)

Typography

  • MaterialTheme.typographyをTextに使用
  • 活字の設定可能
.kt
Text(
    text = msg.body,
    // Textに対してbody2を適用
    style = MaterialTheme.typography.body2
)

Shape

  • Surface関数でコンポーズ可能な関数をラップ
  • Surface関数にMaterialTheme.shapesを使って設定可能
.kt
// shapes.mediumを適用
Surface(shape = MaterialTheme.shapes.medium, elevation = 1.dp) {
    Text(
        text = msg.body,
        modifier = Modifier.padding(all = 4.dp),
        style = MaterialTheme.typography.body2
    )
}

ダークテーマを有効

  • マテリアルデザインのサポートでダークテーマを処理可能
    • ダークモード有効で自動的に調整
  • Preview内でも設定する事で確認可能
.kt
// 通常モードのプレビュー
@Preview(name = "Light Mode")
// ダークモードのプレビュー
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)

レッスン4 リストとアニメーション

アプリ内のあらゆる場所で使われるリストとアニメーションを、Composeを使って簡潔に実装

メッセージのリストを作成

  • LazyColumn, LazyRowで複数要素を扱う
    • items()でパラメータでListを受け取れる
    • 画面上で表示される要素のみレンダリング
.kt
@Composable
fun Conversation(messages: List<Message>) {
    LazyColumn {
        // 扱うListを受け取る
        items(messages) { message ->
            // 1つごとの要素に対してComposable関数を適用
            MessageCard(message)
        }
    }
}

展開時のアニメーション

展開されているというUI状態を保存をするためにremember関数とmutableStateOf関数を使ってトラッキングを行う

  • remember:ローカル状態をメモリに格納
  • mutableStateOf:ここに渡された値をトラッキングに用いる

rememberやmutableStateOfなどの状態を扱う関数を使うことで、状態の変更によるUIの自動更新が可能
→これを再コンポーズという

.kt
// rememberで展開状態を保持
var isExpanded by remember { mutableStateOf(false) }
// 展開状態によって色をアニメーション状に変える変数
val surfaceColor by animateColorAsState(
    if (isExpanded) MaterialTheme.colors.primary else MaterialTheme.colors.surface,
)

// タップによる展開状態を反映
Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
    Text(
        text = msg.author,
        color = MaterialTheme.colors.secondaryVariant,
        style = MaterialTheme.typography.subtitle2
    )

    Spacer(modifier = Modifier.height(4.dp))

    Surface(
        shape = MaterialTheme.shapes.medium,
        elevation = 1.dp,
        // 展開状態でアニメーション状に色が変わる値を代入
        color = surfaceColor,
        // 1dpずつ展開が拡大していくよう設定
        modifier = Modifier.animateContentSize().padding(1.dp)
    ) {
       Text(
           text = msg.body,
           modifier = Modifier.padding(all = 4.dp),
            // メッセージが展開されている時は全体表示
            maxLines = if (isExpanded) Int.MAX_VALUE else 1,
            style = MaterialTheme.typography.body2
        )
    }
}

成果物

チュートリアルを最後まで実施して出来上がる成果物がこちら
アニメーション展開可能な、アイコン, 名前, メッセージが要素のメッセージリストが出来上がる

まとめ

コンポーズ可能な関数とは

  • @Composableをつける事で宣言可能な関数
  • アプリのUIをプログラムで定義可能

コンポーズ可能な関数の種類

  • setContent:レイアウトを定義
  • Text:テキスト
  • Column:縦に要素を並べる
  • Row:横に要素を並べる
  • Box:要素を積み重ねる
  • Image:画像を扱う
  • Modifier:要素の様々な設定
    • コンポーザブルのサイズ、レイアウト、外観の変更
      • padding,widh,height
      • clip,borderなど
    • クリック可能などのインタラクションを追加
      • clickable
    • アニメーションに関する設定
      • animateContentSize
  • プロジェクト名+Theme:マテリアルデザインの適用
    • Color:色
    • Typography:活字
    • Shape:形状
  • LazyColumn,LazyRow:リストを表示、itemsで要素を扱う
  • remember,mutableStateOf:状態をローカルに保持して再コンポーズに使用
  • animateColorAsState:状態によって表示を変える

プレビュー

  • @PreviewアノテーションでAndroidStudio状で表示の確認可能
    • ダークモードも確認可能

感想

今回Composeにおける多くの要素を学んだが、まだ慣れておらずxmlの方がどの要素に何があるかを理解しやすいなと思った。(慣れれば変わると期待)
LazyColumnやLazyRowを使ってこれまでRecyclerViewでやっていた事を置き換えるとなった時に、どの程度の複雑さになるかが気になった。
次回はCompose思想を学ぶ予定

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?