Compose では、複数の修飾子を連鎖させて、コンポーザブルの外観を変更できます。これらの修飾子チェーンは、幅と高さの境界を定義するコンポーザブルに渡される制約に影響する可能性があります。
このページでは、連鎖した修飾子が制約に影響し、その結果としてコンポーザブルの測定と配置に影響する仕組みについて説明します。
UI ツリー内の修飾子
修飾子が互いにどのように影響するかを理解するには、コンポジション フェーズで生成される UI ツリーでの修飾子の表示を視覚化すると便利です。詳細については、構成のセクションをご覧ください。
UI ツリーでは、レイアウト ノードのラッパー ノードとして修飾子を視覚化できます。

コンポーザブルに複数の修飾子を追加すると、修飾子のチェーンが作成されます。複数の修飾子を連結すると、各修飾子ノードはチェーンの残りの部分とレイアウト ノードをラップします。たとえば、clip
修飾子と size
修飾子を連結すると、clip
修飾子ノードが size
修飾子ノードをラップし、その size
修飾子ノードが Image
レイアウト ノードをラップします。
レイアウト フェーズでは、ツリーを走査するアルゴリズムは同じですが、各修飾子ノードも訪問されます。これにより、修飾子は、ラップする修飾子またはレイアウト ノードのサイズ要件と配置を変更できます。
図 2 に示すように、Image
コンポーザブルと Text
コンポーザブルの実装自体は、単一のレイアウト ノードをラップする修飾子のチェーンで構成されています。Row
と Column
の実装は、子をレイアウトする方法を記述するレイアウト ノードにすぎません。

まとめ
- 修飾子は、単一の修飾子またはレイアウト ノードをラップします。
- レイアウト ノードは複数の子ノードをレイアウトできます。
以降のセクションでは、このメンタルモデルを使用して、修飾子の連鎖と、それがコンポーザブルのサイズに及ぼす影響について説明します。
レイアウト フェーズの制約
レイアウト フェーズでは、3 ステップのアルゴリズムに従って、各レイアウト ノードの幅、高さ、x 座標、y 座標を特定します。
- 子を測定する: ノードが子(存在する場合)を測定します。
- ノード自体のサイズを決定する: これらの測定値に基づいて、ノードは独自のサイズを決定します。
- 子を配置: 各子ノードは、ノード自身の位置を基準にして配置されます。
Constraints
は、アルゴリズムの最初の 2 つのステップでノードの適切なサイズを見つけるのに役立ちます。制約は、ノードの幅と高さの最小値と最大値の境界を定義します。ノードがサイズを決定するとき、測定されたサイズはこのサイズ範囲内に収まる必要があります。
制約の種類
制約は次のいずれかになります。
- 境界あり: ノードの幅と高さに最大値と最小値があります。

- 制限なし: ノードのサイズに制限はありません。最大の幅と高さの境界は無限大に設定されます。

- 完全一致: ノードは正確なサイズ要件に従うように求められます。最小値と最大値の境界は同じ値に設定されます。

- 組み合わせ: ノードは上記の制約タイプの組み合わせに従います。たとえば、制約によって幅を制限し、高さの上限を制限しないようにしたり、幅を正確に設定して高さを制限したりできます。

次のセクションでは、これらの制約が親から子に渡される方法について説明します。
制約が親から子に渡される仕組み
レイアウト フェーズの制約で説明したアルゴリズムの最初のステップでは、制約が UI ツリーの親から子に渡されます。
親ノードが子ノードを測定するとき、各子ノードに制約を提供して、許容されるサイズを知らせます。次に、自身のサイズを決定する際に、自身の親から渡された制約にも準拠します。
アルゴリズムの概要は次のとおりです。
- 実際に占有するサイズを決定するために、UI ツリーのルートノードは子を測定し、同じ制約を最初の子に転送します。
- 子が測定に影響しない修飾子である場合、制約を次の修飾子に転送します。制約は、測定に影響する修飾子に到達するまで、修飾子チェーンをそのまま渡されます。制約はそれに応じてサイズ変更されます。
- 子を持たないノード(リーフノード)に到達すると、渡された制約に基づいてサイズを決定し、解決されたサイズを親に返します。
- 親は、この子の測定値に基づいて制約を調整し、調整された制約を使用して次の子を呼び出します。
- 親のすべての子が測定されると、親ノードは自身のサイズを決定し、それを自身の親に伝えます。
- このようにして、ツリー全体が深さ優先でトラバースされます。最終的に、すべてのノードがサイズを決定し、測定ステップが完了します。
詳細な例については、制約と修飾子の順序の動画をご覧ください。
制約に影響する修飾子
前のセクションで、一部の修飾子は制約のサイズに影響する可能性があることを学びました。以降のセクションでは、制約に影響する特定の修飾子について説明します。
size
修飾子
size
修飾子は、コンテンツの推奨サイズを宣言します。
たとえば、次の UI ツリーは 200dp
の 300dp
のコンテナでレンダリングされる必要があります。制約は境界設定されており、幅は 100dp
~300dp
、高さは 100dp
~200dp
の範囲で許可されます。

size
修飾子は、渡された値に一致するように受信した制約を調整します。この例では、値は 150dp
です。

size
修飾子で制約を 150dp
に調整します。幅と高さが最小の制約境界より小さい場合、または最大の制約境界より大きい場合、修飾子は渡された制約をできるだけ厳守しながら、渡された制約にできるだけ近い値に一致させます。

size
修飾子は、渡された制約にできるだけ忠実に従います。複数の size
修飾子を連鎖させても機能しません。最初の size
修飾子は、最小値と最大値の両方の制約を固定値に設定します。2 つ目のサイズ変更子がより小さいサイズまたはより大きいサイズをリクエストした場合でも、渡された正確な境界に準拠する必要があるため、これらの値はオーバーライドされません。

size
修飾子のチェーン。ここで、渡された 2 番目の値(50dp
)は最初の値(100dp
)をオーバーライドしません。requiredSize
修飾子
ノードで制約をオーバーライドする必要がある場合は、size
ではなく requiredSize
修飾子を使用します。requiredSize
修飾子は、受信した制約を置き換え、指定したサイズを正確な境界として渡します。
サイズがツリーを上方向に渡されると、子ノードは利用可能なスペースの中央に配置されます。

size
修飾子からの制約をオーバーライドする requiredSize
修飾子。width
修飾子と height
修飾子
size
修飾子は、制約の幅と高さの両方を調整します。width
修飾子を使用すると、幅を固定して高さを未定にできます。同様に、height
修飾子を使用すると、高さを固定して幅を未決定にできます。

width
修飾子と height
修飾子は、それぞれ固定の幅と高さを設定します。sizeIn
修飾子
sizeIn
修飾子を使用すると、幅と高さの最小値と最大値を正確に設定できます。制約を細かく制御する必要がある場合は、sizeIn
修飾子を使用します。

minWidth
、maxWidth
、minHeight
、maxHeight
が設定された sizeIn
修飾子。例
このセクションでは、複数の修飾子をチェーンしたコード スニペットの出力を示し、説明します。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
このスニペットは、次の出力を生成します。
fillMaxSize
修飾子は、制約を変更して、最小幅と最小高さを最大値(幅は300dp
、高さは200dp
)に設定します。size
修飾子は50dp
のサイズを使用しようとしますが、それでも受信した最小制約に従う必要があります。そのため、size
修飾子は300
の正確な制約境界も200
で出力し、size
修飾子で指定された値を事実上無視します。Image
はこれらの境界に従い、300
×200
のサイズを報告します。このサイズはツリーの上位に渡されます。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
このスニペットは、次の出力を生成します。
fillMaxSize
修飾子は、制約を適応させて、幅と高さの両方の最小値を最大値(幅は300dp
、高さは200dp
)に設定します。wrapContentSize
修飾子は最小制約をリセットします。そのため、fillMaxSize
は固定制約をもたらしますが、wrapContentSize
は制限付き制約にリセットします。次のノードは、再びスペース全体を占有するか、スペース全体よりも小さくなります。size
修飾子は、50
の最小値と最大値の境界に制約を設定します。Image
は50
×50
のサイズに解決され、size
修飾子がそれを転送します。wrapContentSize
修飾子には特別なプロパティがあります。子を受け取り、渡された使用可能な最小境界の中央に配置します。したがって、親に伝えるサイズは、渡された最小境界と同じになります。
3 つの修飾子を組み合わせるだけで、コンポーザブルのサイズを定義し、親の中央に配置できます。
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
このスニペットは、次の出力を生成します。
clip
修飾子は制約を変更しません。padding
修飾子は最大制約を下げます。size
修飾子は、すべての制約を100dp
に設定します。Image
はこれらの制約に従い、サイズを100
×100dp
として報告します。padding
修飾子はすべてのサイズに10dp
を追加するため、報告される幅と高さが20dp
増加します。- 描画フェーズでは、
clip
修飾子は120
×120dp
のキャンバスで動作します。そのため、そのサイズの円形マスクが作成されます。 padding
修飾子は、すべてのサイズでコンテンツを10dp
だけインセットするため、キャンバスのサイズは100
から100dp
に縮小されます。Image
はそのキャンバスに描画されます。画像は120dp
の元の円に基づいてクリップされるため、出力は丸くない結果になります。