Compose for Android

如何在jetpack compose中构建重叠布局

2022-09-01  本文已影响0人  程序员DS

在本文中,我们将构建一个 UI,其中一个可组合内容的内容将重叠在另一个上(正如您通常在社交资料中发现的,其中个人资料图像在封面/背景图像上重叠),如下所示

我们将构建两个相互重叠的盒子。第一个盒子是大内盒(作为封面图片),而第二个盒子是小外盒(作为个人资料图片)。

为此,首先我们需要构建一个自定义布局来计算重叠框的大小并相应地放置它们。

@Composable
fun OverlappingBoxes(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit,
) {
    Layout(
        modifier = modifier,
        content = content,
    ) { measurables, constraints ->
        val largeBox = measurables[0]
        val smallBox = measurables[1]
        val looseConstraints = constraints.copy(
            minWidth = 0,
            minHeight = 0,
        )
        val largePlaceable = largeBox.measure(looseConstraints)
        val smallPlaceable = smallBox.measure(looseConstraints)
        layout(
            width = constraints.maxWidth,
            height = largePlaceable.height + smallPlaceable.height / 2,
        ) {
            largePlaceable.placeRelative(
                x = 0,
                y = 0,
            )
            smallPlaceable.placeRelative(
                x = (constraints.maxWidth - smallPlaceable.width) / 2,
                y = largePlaceable.height - smallPlaceable.height / 2
            )
        }
    }
}

现在,我们将构建一个包含我们 UI 的实际内容的可组合对象,并将其传递给OverlappingBoxes

@Composable
fun CoverAndProfileImage(
    modifier: Modifier = Modifier,
    coverImage: Any?,
    profileImage: Any?,
    onCoverClick: () -> Unit = {},
    onProfileClick: () -> Unit = {},
) {
    OverlappingBoxes(modifier = modifier.fillMaxWidth()) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .height(150.dp)
                .clickable { onCoverClick() }
        ) {
            ImageItem(
                modifier = Modifier.fillMaxSize(),
                data = coverImage ?: R.drawable.default_cover_image,
                contentScale = ContentScale.FillWidth
            )
        }

        Box(
            modifier = Modifier
                .size(100.dp)
                .clip(RoundedCornerShape(16.dp))
                .clickable{ onProfileClick() }
        ) {
            ImageItem(
                modifier = Modifier.fillMaxSize(),
                data = profileImage ?: R.drawable.default_profile_image,
                contentScale = ContentScale.Crop
            )
        }
    }
}

@Composable
fun ImageItem(
    modifier: Modifier,
    data: Any?,
    crossfadeValue: Int = 300,
    contentDescription: String? = null,
    contentScale: ContentScale = ContentScale.Crop
) {
    coil.compose.AsyncImage(
        modifier = modifier,
        model = ImageRequest.Builder(LocalContext.current)
            .data(data)
            .crossfade(crossfadeValue)
            .build(),
        contentDescription = contentDescription,
        placeholder = painterResource(id = R.drawable.placeholder),
        contentScale = contentScale
    )
}

您可以使用以下预览配置查看 UI 的运行情况

@Preview
@Composable
fun CoverAndProfileImagePreview() {
    CoverAndProfileImage(
        coverImage= "https://9to5google.com/wp-content/uploads/sites/4/2021/02/android-jetpack-header.png",
        profileImage= "https://3.bp.blogspot.com/-VVp3WvJvl84/X0Vu6EjYqDI/AAAAAAAAPjU/ZOMKiUlgfg8ok8DY8Hc-ocOvGdB0z86AgCLcBGAsYHQ/s1600/jetpack%2Bcompose%2Bicon_RGB.png"
    )
}

如果您已经做到了这一点,请关注我以获得更多关于 android 开发的有趣文章。

谢谢你。

上一篇下一篇

猜你喜欢

热点阅读