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

この記事からわかること
- Kotlin/Android Jetpack Composeの使い方
- Modifierの種類
- サイズ調整や位置、余白、影、枠線、背景色、タップジェスチャー
- カスタムModifierの作成方法
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Koala
- Kotlin:1.9.0
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
の定義を確認してみます。ここでのthis
はModifier
自体でそこからthen
メソッドを呼び出しています。そしてそのthen
メソッドにSizeElement
インスタンスを渡している形になっています。SizeElement
もModifier
を継承したものと思えば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
なら横幅と高さを一括に、width
やheight
なら横幅と高さをそれぞれ指定することができます。
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内など)
align
はBox
などで囲われている場合に自身が親要素内のどこに配置されるかを指定するモディファイアです。
背景色変更
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)
)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。