ParentDataModifier の Density.modifyParentData() で返したデータが IntrinsicMeasurable.parentData に格納されます。
Measureable が IntrinsicMeasurable を実装しているので、MeasurePolicy の MeasureScope.measure() でこのデータを利用できます。
Layout(
content = content,
modifier = modifier
) { measurables, constraints ->
measurables.forEach {
val parentData = measurable.parentData
...
}
...
}
ParentDataModifier interface を実装している Modifier として
- LayoutId
- BoxChildData
- LayoutWeightImpl
- HorizontalAlignModifier
- VerticalAlignModifier
- SiblingsAlignedModifier
この中で LayoutId は自分の Layout でも使うことができます。
Layout(
content = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = "home",
modifier = Modifier.layoutId("icon")
)
Text(
text = "home",
modifier = Modifier.layoutId("text")
)
},
modifier = modifier
) { measurables, constraints ->
val iconMeasurable = measurables.first { it.layoutId == "icon" }
val textMeasurable = measurables.first { it.layoutId == "text" }
...
}
Modifier.layoutId() は LayoutId を適用した Modifier を返すメソッドです。
@Stable
fun Modifier.layoutId(layoutId: Any) = this.then(
LayoutId(
layoutId = layoutId,
inspectorInfo = debugInspectorInfo {
name = "layoutId"
value = layoutId
}
)
)
LayoutId は ParentDataModifier と LayoutIdParentData を実装した Modifier で、Density.modifyParentData() では LayoutId 自身を返します。
@Immutable
private class LayoutId(
override val layoutId: Any,
inspectorInfo: InspectorInfo.() -> Unit
) : ParentDataModifier, LayoutIdParentData, InspectorValueInfo(inspectorInfo) {
override fun Density.modifyParentData(parentData: Any?): Any? {
return this@LayoutId
}
...
}
interface LayoutIdParentData {
val layoutId: Any
}
Measurable.layoutId は parentData から Modifier.layoutId() で渡した layoutId を取得する便利メソッドです。
val Measurable.layoutId: Any?
get() = (parentData as? LayoutIdParentData)?.layoutId
ParentDataModifier を実装した独自 Modifier を用意することができます。
@Immutable
interface MyLayoutScope {
@Stable
fun Modifier.myLayoutData(index: Int): Modifier
}
internal object MyLayoutScopeInstance : MyLayoutScope {
@Stable
override fun Modifier.myLayoutData(index: Int): Modifier {
return this.then(MyLayoutData(index = index))
}
}
@Immutable
private data class MyLayoutData(val index: Int) : ParentDataModifier {
override fun Density.modifyParentData(parentData: Any?): Any? {
return this@MyLayoutData
}
}
val Measurable.index: Int?
get() = (parentData as? MyLayoutData)?.index
0 件のコメント:
コメントを投稿