【Jetpack Compose】Modifierの種類と使い方!カスタムで作成する方法

【Jetpack Compose】Modifierの種類と使い方!カスタムで作成する方法

この記事からわかること

  • Kotlin/Android Jetpack Compose使い方
  • Modifier種類
  • サイズ調整位置余白枠線背景色タップジェスチャー
  • カスタムModifierの作成方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Jetpack Compose自体の基本的な使用方法に関しては以下の記事を参考にしてください。

Modifier

公式リファレンス:Compose modifiers
公式リファレンス:Modifierオブジェクト

ModifierオブジェクトはJetpack ComposeにおいてUI要素のサイズやレイアウト、ジェスチャー、その他の特性を変更または設定するためのオブジェクトです。デフォルトで定義されているTextなどのComposable関数の引数の1つとして渡せるようになっており、柔軟にUIを制御することが可能になっています。

@Composable
fun Text(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    // 〜〜〜〜〜省略
)

Modifierには様々な拡張関数が用意されており呼び出す際にはModifier.メソッド名形式で呼び出していき、メソッドチェーンで異なる拡張関数を呼び出すことができるようになっています。

Text(
    "Hello World!!",
    // 横幅と高さを200dpにする
    Modifier.width(200.dp).height(200.dp)
)

Modifierをメソッドチェーンで続けられる仕組み

例えばModifier.widthの定義を確認してみます。ここでのthisModifier自体でそこからthenメソッドを呼び出しています。そしてそのthenメソッドにSizeElementインスタンスを渡している形になっています。SizeElementModifierを継承したものと思えばOKです。

@Stable
fun Modifier.width(width: Dp) = this.then(
    SizeElement(
        minWidth = width,
        maxWidth = width,
        enforceIncoming = true,
        inspectorInfo = debugInspectorInfo {
            name = "width"
            value = width
        }
    )
)

続いてthenの定義を確認してみると以下のようになっています。ここでは引数で受け取ったModifierが同じものならそのまま、異なるものならModifierを連結して返却しています。このようにModifier複数リスト形式のような形で保持させることでメソッドチェーンで呼び出されて際にリストに追加していくような仕組みになっているようです。

infix fun then(other: Modifier): Modifier =
    if (other === Modifier) this else CombinedModifier(this, other)

サイズ調整

Viewのサイズを調整するためのモディファイアは複数用意されています。sizeなら横幅と高さを一括に、widthheightなら横幅と高さをそれぞれ指定することができます。

Modifier.size(100.dp)               // 幅と高さを100dpに設定
Modifier.width(200.dp)              // 横幅を200dpに設定
Modifier.height(50.dp)              // 高さを50dpに設定
Modifier.fillMaxSize()              // 親要素のサイズまで広がる
Modifier.wrapContentSize()          // 要素の内容に応じたサイズに調整

fillMaxSizeはViewを親要素のサイズに合わせて最大まで広がりますwrapContentSizeではView内にあるコンテンツを表示するのに必要なサイズ分だけ広がります。

位置や余白を調整

Viewに余白を設けたい場合はpaddingを使用します。指定したViewの内部に指定分の余白を付与するものですが、メソッドチェーンで呼び出す順番などでマージン的な使い方も可能です。

Modifier.padding(16.dp)               // 内側の余白を設定
Modifier.offset(x = 10.dp, y = 20.dp) // 任意の位置にオフセット
Modifier.align(Alignment.Center)      // 親の中央に配置(Box内など)

alignBoxなどで囲われている場合に自身が親要素内のどこに配置されるかを指定するモディファイアです。

背景色変更

Viewの背景色を変更するにはbackgroundを指定します。

Modifier.background(Color.Blue)     // 背景色を設定

透明度を変更

Viewの透明度を変更するにはgraphicsLayerを指定します。

Modifier. graphicsLayer(alpha = 0.5f)     //  透明度を設定

枠線を追加

Viewに枠線を追加するにはborderを指定します。引数には枠線の太さとカラーを指定します。

Modifier.border(2.dp, Color.Red)    // 赤い枠線を追加

角丸の枠線にするにはさらに形を渡せばOKです。

Modifier.border(2.dp, Color.Red, shape = RoundedCornerShape(16.dp))

形状を変更

Viewの形状を変更するにはclipを指定します。引数には変更したい形を指定します。

Modifier.clip(CircleShape)          // 円形に切り抜き
Modifier.clip(RoundedCornerShape(8.dp)) // 角丸四角形に切り抜き

影をつける

Viewにドロップシャドウ(影)を付与するにはshadowを指定します。

Modifier.shadow(8.dp)               // ドロップシャドウを追加

ジェスチャーを追加

Viewにタップジェスチャーを付与するにはclickableを使用します。クロージャーには実行したい処理を渡します。

// クリックイベントを追加
Modifier.clickable { 
    println("Clicked!") 
}

他にもドラッグ操作を追加するdraggableやスクロール操作を追加するscrollableなどがあります。

@Preview(showBackground = true)
@Composable
fun DraggableExample() {
    var offsetX = remember { mutableStateOf(0f) } // X座標だけを管理

    Box(
        modifier = Modifier
            .size(100.dp)
            .background(Color.Red)
            .offset { IntOffset(offsetX.value.toInt(), 0) } // ドラッグした位置にビューを移動
            .draggable(
                state = rememberDraggableState { delta ->
                    // deltaはドラッグの移動量
                    offsetX.value += delta // 水平方向のみ更新
                },
                orientation = Orientation.Horizontal // 水平方向にのみドラッグ
            )
    ) {
        Text(text = "HELLO", color = Color.White, modifier = Modifier.align(Alignment.Center))
    }
}

カスタムモディファイアを実装する

既存のモディファイアではなく、独自のモディファイアを作成することも可能です。その場合はthenを使用して以下のように実装すればOKです。

fun Modifier.customPadding(value: Dp): Modifier = this.then(
    Modifier.padding(value * 2)
)

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index