Closed4
Modifier修飾子を見る(2)

参考
https://qiita.com/SUR4J/items/6d18caffd4897a39d010

Modifier#layoutによるレイアウト修飾子の作成
Modifierの拡張関数としてカスタム修飾子は作成可能。
Modifier#layoutによってレイアウトの要素測定と配置の変更が可能。
Modifier#layoutの戻り値の型はModifierのためチェーンが可能。
以下のように書いてみた。
親の中央に配置するというもの。
fun Modifier.setCenter() = layout { measurable, constraints ->
return@layout layout(constraints.maxWidth, constraints.maxHeight) {
val measured = measurable.measure(constraints)
// 画面の中央を計算
val centerPosition = Alignment.Center.align(
size = IntSize(measured.width, measured.height),
space = IntSize(constraints.maxWidth, constraints.maxHeight),
layoutDirection
)
// 配置
measured.place(centerPosition)
}
}
@Composable
fun CustomLayoutModifierTest() {
Text(
text = "Hoge",
Modifier.setCenter(),
)
}
中心に"Hoge"という文字が来ていた。

Modifier#composedによる状態を持たせたカスタム修飾子
インターフェースはこんな感じ。Modifierを作るfactoryを渡せばthenで繋いでくれる。
このfactoryがComposableのためrememberを呼ぶことができ状態を保持できる。
fun Modifier.composed(
inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
factory: @Composable Modifier.() -> Modifier
): Modifier = this.then(ComposedModifier(inspectorInfo, factory))
見様見真似で書いてみた。クリックしたら背景色が変わるようにしてみた。
clickableを内部で使っているため呼び出し元でclickableが効かなくなってしまった。
fun Modifier.clickAndChangeBackground(
callback: () -> Unit,
) = composed {
var isSelected by remember { mutableStateOf(false) }
val backgroundColor = if (isSelected) Color.Red else Color.White
background(backgroundColor)
.then(
clickable {
isSelected = isSelected.not()
callback.invoke()
}
)
}
@Composable
@Preview
fun CustomModifierTest() {
Text(
"text",
modifier = Modifier
.clickAndChangeBackground {
println("Hello World")
}
)
}

composedの第一引数inspectorInfo
デバッグするときに使える。
Layout Inspectorに情報を表示できる。以下のように設定してみた。
fun Modifier.clickAndChangeBackground() = composed(
inspectorInfo = debugInspectorInfo {
name = "clickAndChangeBackground"
properties["test"] = "test"
}
) {
var isSelected by remember { mutableStateOf(false) }
val backgroundColor = if (isSelected) Color.Red else Color.White
background(backgroundColor)
.then(
clickable {
isSelected = isSelected.not()
}
)
}
表示されていた。
このスクラップは2023/10/01にクローズされました