欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Jetpack?Compose入門基礎(chǔ)全面精講

 更新時(shí)間:2022年10月26日 10:08:14   作者:唯鹿  
開始布局部分。這部分我個(gè)人感覺沒有必要每個(gè)組件、屬性都詳細(xì)說到,否則篇幅會(huì)很長(zhǎng)。建立起Compose中的組件與?Android?Views的一個(gè)對(duì)應(yīng)關(guān)系就夠了。具體還是需要在實(shí)際的使用中去熟悉

1. Column

子元素按豎直順序排列,相當(dāng)于豎直方向的LinearLayout。

@Composable
inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    content: @Composable ColumnScope.() -> Unit
)
  • modifier是修飾符,我們放到下一篇詳細(xì)說明。
  • verticalArrangement,指定子元素在Column中的排列方式,默認(rèn)是Top。下圖是文檔給的各屬性示意,很直觀。

  • horizontalAlignment,指定水平方向的對(duì)齊方式,有StartCenterHorizontally,End三種,默認(rèn)Start。這部分和我們的android:gravity屬性類似,這里是通過兩個(gè)屬性分開配置。
  • content,就是我們的子元素,用大括號(hào)包住。
@Composable
fun ArtistCard() {
    Column {
        Text("Alfred Sisley")
        Text("3 minutes ago")
    }
}

2. Row

子元素按水平順序排列,相當(dāng)于水平方向的LinearLayout?;居梅ㄅcColumn一致,簡(jiǎn)單說明一下。

@Composable
inline fun Row(
    modifier: Modifier = Modifier,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    content: @Composable RowScope.() -> Unit
)

horizontalArrangement,指定子元素在水平方向的排列方式,默認(rèn)是Start。直接上圖:

verticalAlignment,指定垂直方向的對(duì)齊方式,有Top、CenterVertically,Bottom三種,默認(rèn)Top。

3. Box

box就像盒子一樣,里面的東西可以層層擺放。大體相當(dāng)于FrameLayout。

@Composable
inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
)

contentAlignment,指定子元素的對(duì)齊方式,八個(gè)方向加一個(gè)正中九種位置,默認(rèn)是左上角(LTR)。這個(gè)屬性我個(gè)人覺得使用頻率不高,主要還是需要單獨(dú)去指定各個(gè)子元素位置(使用Modifieralign方法)。

這里可以看個(gè)文檔中的例子:

	Box {
        Box(Modifier.fillMaxSize().background(Color.Cyan))
        Box(
            Modifier.matchParentSize()
                .padding(top = 20.dp, bottom = 20.dp)
                .background(Color.Yellow)
        )
        Box(
            Modifier.matchParentSize()
                .padding(40.dp)
                .background(Color.Magenta)
        )
        Box(
            Modifier.align(Alignment.Center)
                .size(300.dp, 300.dp)
                .background(Color.Green)
        )
        Box(
            Modifier.align(Alignment.TopStart)
                .size(150.dp, 150.dp)
                .background(Color.Red)
        )
        Box(
            Modifier.align(Alignment.BottomEnd)
                .size(150.dp, 150.dp)
                .background(Color.Blue)
        )
    }

預(yù)覽效果:

Box中的各個(gè)子Box從底部向上疊加。通過align指定位置,通過size、padding調(diào)整大小。matchParentSize類似match_parent屬性,寬高填充滿父布局。

注意:這個(gè)子元素的Box和父元素Box雖然長(zhǎng)得一樣,但實(shí)際不是一個(gè)組件。前者類似于View,不能添加子View,可以指定大小樣式,而后者類似ViewGroup。

propagateMinConstraints,子元素是否使用指定的最小約束,默認(rèn)false。這個(gè)屬性直接這么解釋很抽象,我們可以接著用上面的例子,添加下面的代碼:

	Box(
        Modifier.sizeIn(100.dp, 200.dp),
        propagateMinConstraints = true
    ) {
    ...
    }

我們指定子元素最小寬是100dp,高是200dp后,預(yù)覽效果如下:

可以看到原本的紅藍(lán)色塊因?yàn)楦叨戎挥?50dp,所以被約束為了最小的200dp,變成的長(zhǎng)方形。

4. BoxWithConstraints

BoxWithConstraints和上面的Box很相似,唯一不同是它多了約束。我們先看源碼:

@Composable
fun BoxWithConstraints(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxWithConstraintsScope.() -> Unit
)

注意到不同處是BoxWithConstraintsScope,它繼承自BoxScope。BoxScope就是提供了上面使用到的alignmatchParentSize方法的作用域。

/**
 * Receiver scope being used by the children parameter of [BoxWithConstraints]
 */
@Stable
interface BoxWithConstraintsScope : BoxScope {
    /**
     * The constraints given by the parent layout in pixels.
     *
     * Use [minWidth], [maxWidth], [minHeight] or [maxHeight] if you need value in [Dp].
     */
    val constraints: Constraints
    /**
     * The minimum width in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val minWidth: Dp
    /**
     * The maximum width in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val maxWidth: Dp
    /**
     * The minimum height in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val minHeight: Dp
    /**
     * The maximum height in [Dp].
     *
     * @see constraints for the values in pixels.
     */
    val maxHeight: Dp
}

所以BoxWithConstraints不同就是在Box的基礎(chǔ)上多了最大最小寬度高度的屬性??梢杂盟鼇碜鲆恍╉撁孢m配之類的工作,使用例子如下:

	BoxWithConstraints {
        if (maxWidth < 400.dp) {
            Column {
                Image(/* ... */)
                Title(/* ... */)
            }
        } else {
            Row {
                Column {
                    Title(/* ... */)
                    Description(/* ... */)
                }
                Image(/* ... */)
            }
        }
    }

5. ConstraintLayout

使用 Android View 系統(tǒng)時(shí),在嵌套某些 View(如 RelativeLayout)時(shí),可能會(huì)出現(xiàn)一些性能問題。由于 Compose 可以避免多次測(cè)量,因此可以根據(jù)需要進(jìn)行深層次嵌套,而不會(huì)影響性能。

雖然不用考慮嵌套帶來的性能問題,但是這寫起來一層套一層的也挺鬧心的。加上ConstraintLayout我個(gè)人已經(jīng)非常習(xí)慣使用了,所以也很希望在Compose中也能使用到它。個(gè)人感覺ConstraintLayout 可以提高可讀性。

使用Compose中的ConstraintLayout需要額外添加依賴:

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-rc02"

@Composable
inline fun ConstraintLayout(
    modifier: Modifier = Modifier,
    optimizationLevel: Int = Optimizer.OPTIMIZATION_STANDARD,
    crossinline content: @Composable ConstraintLayoutScope.() -> Unit
)

optimizationLevellayout_optimizationLevel一樣,用來約束優(yōu)化的。默認(rèn)OPTIMIZATION_STANDARD,只優(yōu)化直接約束和barrier約束。通常我們不需要修改它。

這里用官方的一個(gè)例子簡(jiǎn)單說明一下它的使用方法:

	ConstraintLayout(
        modifier = Modifier
            .fillMaxSize()
    ) {
        val (image, header, tag1, tag2, tag3, bSignup, bLogin, disclaimer) = createRefs()
        val g1 = createGuidelineFromStart(44.dp)
        val g2 = createGuidelineFromEnd(44.dp)
        Image(
            modifier = Modifier.constrainAs(image) {
                width = Dimension.value(201.dp)
                height = Dimension.value(179.dp)
                top.linkTo(parent.top, 32.dp)
                start.linkTo(g1)
            },
            painter = painterResource(id = R.drawable.intercom_snooze),
            contentDescription = null
        )
        Text(
            modifier = Modifier.constrainAs(header) {
                top.linkTo(image.bottom, 32.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            text = stringResource(id = R.string.welcome_header),
            style = MaterialTheme.typography.h5,
        )
        Text(
            modifier = Modifier.constrainAs(tag1) {
                top.linkTo(header.bottom, 16.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            text = stringResource(id = R.string.welcome_tagline1)
        )
        Text(
            modifier = Modifier.constrainAs(tag2) {
                top.linkTo(tag1.bottom, 8.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            text = stringResource(id = R.string.welcome_tagline2)
        )
        Text(
            modifier = Modifier.constrainAs(tag3) {
                top.linkTo(tag2.bottom, 8.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            text = stringResource(id = R.string.welcome_tagline3)
        )
        Button(
            modifier = Modifier.constrainAs(bSignup) {
                bottom.linkTo(bLogin.top, 16.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            onClick = {}
        ) {
            Text(text = stringResource(id = R.string.sign_up))
        }
        Button(
            modifier = Modifier.constrainAs(bLogin) {
                bottom.linkTo(disclaimer.top, 16.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            onClick = {},
        ) {
            Text(text = stringResource(id = R.string.log_in))
        }
        Text(
            modifier = Modifier.constrainAs(disclaimer) {
                bottom.linkTo(parent.bottom, 8.dp)
                start.linkTo(g1)
                end.linkTo(g2)
                width = Dimension.fillToConstraints
            },
            text = stringResource(id = R.string.trial_disclaimer),
            style = MaterialTheme.typography.caption,
        )
    }

預(yù)覽效果如下(包括約束效果):

說明一下代碼中的屬性和方法:

  • createRefs()是創(chuàng)建引用。或者說定義需要使用的id。
  • Modifier.constrainAs是定義約束條件。括號(hào)內(nèi)填寫開始創(chuàng)建的引用。類似android:id="@+id/xxx"。
  • createGuidelineFromXXX就是創(chuàng)建一個(gè)Guideline,例子中創(chuàng)建了左右兩個(gè)Guideline作為左右兩邊間距參考線。
  • linkTo是用來指定約束條件的。例如top.linkTo(image.bottom, 32.dp) 相當(dāng)于 app:layout_constraintTop_toBottomOf="@+id/image"android:layout_marginTop="32dp"
  • Dimension.fillToConstraints,填充滿約束,類似寬高指定0dp。

當(dāng)然還有許多的屬性方法沒有用到,也就不詳細(xì)的介紹了,有興趣的可以看官方demo。

到此,基礎(chǔ)布局篇結(jié)束,下一篇詳細(xì)介紹 Modifier修飾符。

6. 參考

Compose 布局基礎(chǔ)知識(shí)

Compose 的標(biāo)準(zhǔn)布局元素

到此這篇關(guān)于Jetpack Compose入門基礎(chǔ)全面精講的文章就介紹到這了,更多相關(guān)Jetpack Compose內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論