Compose 修飾元

修飾元可用於裝飾或增強可組合元件。修飾元可以讓您執行下列操作:

  • 變更可組合元件的大小、版面配置、行為和外觀
  • 新增資訊,例如無障礙標籤
  • 處理使用者輸入內容
  • 新增高等級互動,例如讓元素可供點擊、可捲動、可拖曳或可縮放

修飾元是標準的 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 的子項。 如此可更容易重複使用您的程式碼,讓程式碼的行為更加易於預測,更直覺易懂。詳情請參閱 Compose API 指南:元素接受並修改修飾元參數

修飾元的順序很重要

修飾元函式的順序 很重要。由於每個函式都會對前一個函式傳回的 Modifier 進行變更,因此序列會影響最終結果。範例如下:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

整個區域(包括邊緣周圍的邊框間距)都會回應點擊

在上面的程式碼中,整個區域都是可點擊的,也包括周圍的邊框間距,這是因為在 clickable 修飾元 之後 才套用了 padding 修飾元。如果修飾元順序相反,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.dpImage 的高度也會是 150.dp,因為 requiredSize 修飾元有優先優勢。

便可覆寫這一置中行為。

如果您希望子項版面配置填滿父項允許的所有可用高度,請新增 fillMaxHeight 修飾元(Compose 也提供 fillMaxSizefillMaxWidth):

@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 修飾元,並設定 xy 軸的位移。位移值可以是正數與非正數。paddingoffset 的差異在於,將 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()
    }
}

灰色背景填滿容器

如果使用 fillMaxSize 而不是 matchParentSizeSpacer 會取得父項允許的所有可用空間,進而導致父項能夠展開及填滿所有可用的空間。

灰色背景填滿螢幕

列與欄的權數

如前文 邊框間距和大小 一節的說明,根據預設,可組合元件的大小是由其包裝的內容定義的。您可以使用僅由 RowScopeColumnScope 提供的 weight 修飾元,靈活地在父項範圍內設定可組合元件的大小。

讓我們來看看包含兩個 Box 可組合元件的 Row。 第一個方塊是第二個 weight 的兩倍,因此其寬度也為兩倍。由於 Row 的寬度為 210.dp,因此第一個 Box 寬為 140.dp,第二個為 70.dp

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Image(
            /*...*/
            modifier = Modifier.weight(2f)
        )
        Column(
            modifier = Modifier.weight(1f)
        ) {
            /*...*/
        }
    }
}

圖片寬度為文字寬度的兩倍

瞭解詳情

我們提供修飾元的完整清單,以及其中的參數和範圍。