修飾子を使用すると、コンポーザブルを装飾または拡張できます。修飾子では、次のようなことができます。
- コンポーザブルのサイズ、レイアウト、動作、外観を変更する
- ユーザー補助ラベルなどの情報を追加する
- ユーザー入力を処理する
- 要素をクリック可能、スクロール可能、ドラッグ可能、ズーム可能にするなど、高レベルの操作を追加する
修飾子は標準の Kotlin オブジェクトです。Modifier
クラス関数のいずれかを呼び出して修飾子を作成します。
import androidx.compose.ui.Modifier
@Composable
private fun Greeting(name: String) {
Column(modifier = Modifier.padding(24.dp)) {
Text(text = "Hello,")
Text(text = name)
}
}
こうした関数を連鎖させてコンポーズできます。
@Composable
private fun Greeting(name: String) {
Column(modifier = Modifier
.padding(24.dp)
.fillMaxWidth()
) {
Text(text = "Hello,")
Text(text = name)
}
}
上記のコードでは、さまざまな修飾子関数を一緒に使用しています。
padding
は、要素の周囲にスペースを挿入します。fillMaxWidth
は、コンポーザブルを親から与えられた最大幅に合わせて調整します。
おすすめの方法は、コンポーザブルのすべてが modifier
パラメータを受け取り、その修飾子を UI を、UI を出力する最初の子に渡すようにすることです。これにより、コードの再利用性が向上し、動作が予測可能で直感的になります。詳しくは、Compose API のガイドライン「要素が修飾子パラメータを受け取って準拠する」についての説明をご覧ください。
修飾子の順序の重要性
修飾子関数の順序は重要です。各関数は前の関数が返す Modifier
を変更するため、順序は最終結果に影響を与えます。次の例をご覧ください。
@Composable
fun ArtistCard(/*...*/) {
val padding = 16.dp
Column(
Modifier
.clickable(onClick = onClick)
.padding(padding)
.fillMaxWidth()
) {
// rest of the implementation
}
}
上記のコードでは、padding
修飾子が clickable
修飾子の後に適用されるため、周囲のパディングを含むエリア全体がクリック可能となります。修飾子の順序が逆の場合、padding
で追加されたスペースはユーザー入力に反応しません。
@Composable
fun ArtistCard(/*...*/) {
val padding = 16.dp
Column(
Modifier
.padding(padding)
.clickable(onClick = onClick)
.fillMaxWidth()
) {
// rest of the implementation
}
}
組み込み修飾子
Jetpack Compose には、コンポーザブルの装飾や拡張に役立つ組み込み修飾子のリストが用意されています。レイアウトの調整に使用する一般的な修飾子は次のとおりです。
パディングとサイズ
Compose で提供されるレイアウトは、デフォルトでは子をラップしていますが、size
修飾子を使用してサイズを設定できます。
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.size(width = 400.dp, height = 100.dp)
) {
Image(/*...*/)
Column { /*...*/ }
}
}
指定したサイズがレイアウトの親の制約を満たさない場合、そのサイズが適用されないことがあります。親の制約に関係なくコンポーザブルのサイズを固定する必要がある場合は、requiredSize
修飾子を使用します。
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.size(width = 400.dp, height = 100.dp)
) {
Image(
/*...*/
modifier = Modifier.requiredSize(150.dp)
)
Column { /*...*/ }
}
}
この例では、親 height
が 100.dp
に設定されていても、requiredSize
修飾子が優先されるため、Image
の高さは 150.dp
になっています。
親によって許可されているすべての高さを子レイアウトで埋めるには、fillMaxHeight
修飾子を追加します(Compose では、fillMaxSize
と fillMaxWidth
も提供されています)。
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.size(width = 400.dp, height = 100.dp)
) {
Image(
/*...*/
modifier = Modifier.fillMaxHeight()
)
Column { /*...*/ }
}
}
要素全体にパディングを追加するには、padding
修飾子を設定します。
テキストのベースラインの上にパディングを追加して、レイアウトの上部からベースラインまで一定の距離を空ける場合は、paddingFromBaseline
修飾子を使用します。
@Composable
fun ArtistCard(artist: Artist) {
Row(/*...*/) {
Column {
Text(
text = artist.name,
modifier = Modifier.paddingFromBaseline(top = 50.dp)
)
Text(artist.lastSeenOnline)
}
}
}
オフセット
レイアウトを元の位置に対して相対的に配置するには、次のように offset
修飾子を追加し、x 軸と y 軸でオフセットを設定します。オフセットは、正の数でも負の数でもかまいません。padding
と offset
の違いは、offset
をコンポーザブルに追加しても測定値自体は変更されない点です。
@Composable
fun ArtistCard(artist: Artist) {
Row(/*...*/) {
Column {
Text(artist.name)
Text(
text = artist.lastSeenOnline,
modifier = Modifier.offset(x = 4.dp)
)
}
}
}
offset
修飾子は、レイアウト方向に従って横方向に適用されます。正の offset
を設定する場合、左から右方向のコンテキストでは要素が右に移動し、右から左方向のコンテキストでは要素が左に移動します。レイアウト方向を考慮せずにオフセットを設定する必要がある場合は、absoluteOffset
修飾子をご覧ください。この修飾子を使用すると、正のオフセット値を設定した場合に要素が常に右へ移動します。
Compose での型の安全性
Compose には、特定のコンポーザブルの子に適用される場合にのみ動作する修飾子があります。たとえば、Box
サイズに影響を与えずに子を親の Box
と同じサイズにするには、matchParentSize
修飾子を使用します。
Compose では、カスタム スコープによってこの型の安全性が適用されます。たとえば、matchParentSize
は BoxScope
でのみ使用できます。そのため、この修飾子を使用できるのは Box
内で子が使用されている場合に限られます。
スコープ修飾子は、子に関して親が知っておくべき情報を親に通知します。これは、一般に親データ修飾子とも呼ばれます。その内部構造は汎用修飾子とは異なりますが、使用方法の観点から見るとこれらの違いは重要ではありません。
Box の matchParentSize
前述のように、Box
サイズに影響を与えずに子レイアウトを親 Box
と同じサイズにする場合は、matchParentSize
修飾子を使用します。
matchParentSize
は Box
スコープ内でしか使用できず、Box
コンポーザブルの直接の子にのみ適用されます。
以下の例では、子 Spacer
は親 Box
からサイズを取得し、親はそのサイズを最も大きな子(この場合は ArtistCard
)から取得しています。
@Composable
fun MatchParentSizeComposable() {
Box {
Spacer(Modifier.matchParentSize().background(Color.LightGray))
ArtistCard()
}
}
matchParentSize
ではなく fillMaxSize
を使用した場合、Spacer
は親が使用できるすべてのスペースを使用します。この場合、親は使用可能なスペース全体に拡大します。
行と列の比
前のセクションのパディングとサイズで説明したように、デフォルトでは、コンポーザブルのサイズは自身がラップするコンテンツによって定義されます。RowScope
と ColumnScope
でのみ使用可能な weight
修飾子を使用すると、コンポーザブルのサイズを親の内部で柔軟に変動するように設定することもできます。
たとえば、2 つの Box
コンポーザブルが含まれる Row
があるとします。最初のボックスには、2 番目のボックスの 2 倍の weight
が指定されているため、幅も 2 倍になります。Row
の幅は 210.dp
なので、最初の Box
の幅は 140.dp
、2 番目のボックスの幅は 70.dp
になります。
@Composable
fun ArtistCard(/*...*/) {
Row(
modifier = Modifier.fillMaxWidth()
) {
Image(
/*...*/
modifier = Modifier.weight(2f)
)
Column(
modifier = Modifier.weight(1f)
) {
/*...*/
}
}
}
詳細
修飾子の全リストと、各修飾子のパラメータとスコープを紹介します。