簡體   English   中英

Jetpack Compose 中的修飾符 fillMaxWidth() 和 wrapContentWidth()

[英]Modifiers fillMaxWidth() and wrapContentWidth() in Jetpack Compose

我對 Jetpack Compose 中的修飾符 fillMaxWidth() 和 wrapContentWidth() 的作用感到困惑。 我已經通讀了文檔並查看了它們的實現,但我仍然不確定它們是如何工作的(內部)。

以下是我對他們所做工作的理解:

  • fillMaxWidth() 將元素的寬度設置為其父容器的最大寬度。 我的理解是,它通過將最小寬度和最大寬度設置為等於父級的最大寬度來實現。

  • wrapContentWidth() 使布局元素與元素的內容一樣寬。

我的問題是:

  1. 在 fillMaxWidth() 的情況下,我對它在內部所做的事情的理解是否正確(將最小寬度和最大寬度設置為等於父級的最大寬度)?

  2. 在 wrapContentWidth() 的情況下,是否通過將元素的最小和最大寬度設置為內容的寬度來使布局元素與元素的內容一樣寬?

  3. 另外,如果我將以下修飾符應用於元素,它究竟會做什么? modifier = Modifier.fillMaxWidth().wrapContentWidth() 難道 wrapContentWidth()不會撤銷 fillMaxWidth 所做的事情嗎? 如果我切換順序並使用modifier = Modifier.wrapContentWidth().fillMaxWidth()怎么辦?

感謝所有幫助。

  • fillMaxWidth()將組合的最小和最大寬度設置為容器允許的最大值,以填充所有空間
  • wrapContentWidth()會將最小寬度設置為 0(因此忽略之前的最小寬度),如果將 unbounded 設置為 true,則可以對最大寬度執行相同的操作

您可以將它們組合起來產生一些效果,例如,您可以使用fillMaxWidth來設置特定的背景顏色,然后使用wrapContentWidthwrapContentHeight在同一容器中居中設置子可組合項,如此處所示(我使用wrapContentSize但同樣適用於wrapContentWidthwrapContentHeight

@Preview(widthDp = 360, heightDp = 360)
@Composable
private fun PreviewMOdifier() {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.Red)
            .wrapContentSize(Alignment.Center)
            .background(Color.Blue)
    ) {
        Text(
            text = "This is the body",
            modifier = Modifier
                .padding(all = 16.dp)
                .background(Color.Yellow)
        )
    }
}

在此處輸入圖像描述

編輯:這是另一個示例,嘗試在Box修飾符中刪除wrapContentHeight ,以便查看預覽如何變化

@Preview(heightDp = 360)
@Composable
private fun PreviewThreeBlock() {
    PlaygroundTheme {
        Surface(
            color = MaterialTheme.colorScheme.background
        ) {
            Box(
                modifier = Modifier.wrapContentHeight().background(Color.Red)
            ) {
                Text(text = "FooBar")
            }
        }
    }
}

在 Jetpack Compose 中,子項或/和容器可組合項的大小設置是使用來自大小修改器、父項或滾動條的Constraints來完成的,因為它們返回 Constraints.Infinity。

測量具有父級或修改后的約束的可組合項確定子可組合項的大小

您可以查看此答案的約束部分。

Modifier.fillmaxWidth(fraction)將 Constraints 的最小和最大寬度設置為相等,因此當您調用 measurable.measure(constraints) 時,您的子 Composable 將使用此固定值進行測量。

當您的父可組合項是行、列或其他內置可組合項時,實際上大多數情況下不需要 Modifier.wrapWidth(),因為當您沒有為可組合項分配大小修飾符時,它是根據最小-最大約束范圍測量的parent 是介於 0 和父寬度之間的范圍。

但是, Box有一個名為propagateMinConstraintsSurface的參數,它是一個Box with propagateMinConstraints = true強制最小Constraints到直接后代,如本答案或@Francesc 解釋的那樣。

在此處輸入圖像描述

@Composable
private fun WrapWidthExample() {
    Row() {
        Surface(
            modifier = Modifier
                .size(200.dp)
                .border(2.dp, Color.Yellow),
            onClick = {}) {
            Column(
                modifier = Modifier
                    .size(50.dp)
                    .background(Color.Red, RoundedCornerShape(6.dp))
            ) {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Green, RoundedCornerShape(6.dp))
                )

            }
        }
        Surface(
            modifier = Modifier
                .size(200.dp)
                .border(2.dp, Color.Yellow),
            onClick = {}) {
            Column(
                modifier = Modifier
                    .wrapContentWidth()
                    .background(Color.Red, RoundedCornerShape(6.dp))
            ) {
                Box(
                    modifier = Modifier
                        .size(50.dp)
                        .background(Color.Green, RoundedCornerShape(6.dp))
                )

            }
        }
    }
}

沒有Modifier.wrapContentWidth() 200.dp(在我的設備中為 525px)被強制為紅色 Column 以測量Measurable ,但是 wrapContentWidth 允許 Composable 使用它自己的最小約束,這是 0 因為沒有分配任何修飾符。

  • 允許內容以其所需的寬度進行測量,而不考慮傳入的測量值 * [最小寬度約束][Constraints.minWidth],並且,如果 [unbounded] 為真,也無需 *考慮傳入的測量值 [最大寬度約束][約束.maxWidth]。 如果 * 內容的測量尺寸小於最小寬度約束,[對齊] * 它在最小寬度空間內。 如果內容的測量大小大於最大 * 寬度約束(僅當 [unbounded] 為真時才可能),[對齊] 在最大 * 寬度空間上。

從這個修改器返回的約束是

    val wrappedConstraints = Constraints(
        minWidth = if (direction != Direction.Vertical) 0 else constraints.minWidth,
        minHeight = if (direction != Direction.Horizontal) 0 else constraints.minHeight,
        maxWidth = if (direction != Direction.Vertical && unbounded) {
            Constraints.Infinity
        } else {
            constraints.maxWidth
        },
        maxHeight = if (direction != Direction.Horizontal && unbounded) {
            Constraints.Infinity
        } else {
            constraints.maxHeight
        }
    )

基本上,當父強制子可組合項使用其約束時,可以使用 wrapContentX,這可以在您構建自定義布局時完成,例如或使用上面的 Surface。

  1. 在 Jetpack Compose 中,除非您鏈接 Modifier.requiredX,否則將應用第一個大小修飾符,而在它之后的修飾符將被忽略,除非它們之間沒有填充、大小等。 您可以在第一個鏈接中查看 requiredSize 答案以獲取更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM