1

在我们的应用程序中,有许多自定义视图都是带有 3 个插槽标题、内容和底部部分的卡片,所以我认为我们可以使用卡片内部的脚手架来处理它,除非有许多if/else条件

所以我创建了这个基本的可组合函数->

@Composable
fun DynamicTile(
    modifier: Modifier = Modifier,
    headContent: @Composable () -> Unit,
    mainContent: @Composable (PaddingValues) -> Unit = { },
    bottomContent: @Composable () -> Unit = { }
) {
    Card( modifier = modifier) {
        Scaffold(
            topBar = headContent,
            content = mainContent,
            bottomBar = bottomContent
        )
    }
}

然后针对不同目的进行不同的实现,我在这里提到两个目的,例如显示特定的图像、动画、地图和...->

对于这个,您应该将本地可绘制对象添加到图像以编译它

@Composable
fun TileTeaser( modifier: Modifier = Modifier) {
    with(entity) {
        DynamicTile(
//            modifier = modifier.then(Modifier.height(250.dp)),
            headContent = {
                Text(
                    text = "headline",
                   
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(start = 16.dp, end = 16.dp, top = 8.dp)
                )
            },
            mainContent = {
                 val painter = rememberImagePainter(
                    data = painterResource(R.drawable.ds_ic_add))
                Image(
                    contentScale = ContentScale.Crop,
                    painter = painter,
                    modifier = modifier,
                    contentDescription = null
                )
            },
            bottomContent = {
                     Box(modifier = Modifier.fillMaxWidth()) {
                    Button(
                        onClick = { }, modifier = Modifier
                            .align(Alignment.Center)
                            .wrapContentSize()
                    ) {
                        Text(text = "Button")
                    }
                }
                }
            }
        )
    }
}

而这个用于 Lottie 的动画,你应该添加本地 raw 来编译它

@Composable
fun TileAnimation(modifier: Modifier = Modifier) {
    DynamicTile(
        modifier = modifier.then(Modifier.height(300.dp)),
        headContent = {
            Text(
                text = "headline",
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 16.dp, end = 16.dp, top = 8.dp)
            )
        },
        mainContent = {
            val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.sth))
            Card(
                modifier = Modifier
                    .height(183.dp)
                    .then(modifier),
                shape = RoundedCornerShape(0.dp)
            ) {
                LottieAnimation(
                    composition = composition,
                    modifier = modifier
                        .fillMaxSize(),
                    contentScale = ContentScale.Crop,
                )
            }
        },
        bottomContent = {
            Box(modifier = Modifier.fillMaxWidth()) {
                Button(
                    onClick = { }, modifier = Modifier
                        .align(Alignment.Center)
                        .wrapContentSize()
                ) {
                    Text(text = "Button")
                }
            }
        }
    )
}

然后我将它们加载到这样的列中

@Composable
fun LoadScreen() {
    Column(
        modifier = Modifier
            .padding(16.dp)
            .verticalScroll(rememberScrollState())
    ) {
        Text(text = "Teaser")

        TileTeaser(
            modifier = Modifier.padding(top = 16.dp)
        )
        
        Text(
            text = "Animation",
            modifier = Modifier.padding(top = 16.dp)
        )

        TileAnimation(modifier = Modifier.padding(vertical = 16.dp))
    }
}

如您所见,如果我评论卡的Modifier.height,它会因此错误而崩溃->

  java.lang.IllegalArgumentException: Can't represent a size of 2147483563 in Constraints
        at androidx.compose.ui.unit.Constraints$Companion.bitsNeedForSize(Constraints.kt:408)
        at androidx.compose.ui.unit.Constraints$Companion.createConstraints-Zbe2FdA$ui_unit_release(Constraints.kt:368)

Kotlin 版本 1.6.10 和 compose 1.1.0,这是 lottie 库->

implementation "com.airbnb.android:lottie-compose:4.2.2"

顺便说一句,你可以从这里下载 Lottie 文件

预先感谢您的帮助

4

1 回答 1

2

TL;DR 不要将 a Scaffoldinside aCard放入可滚动内容中。:)

如果我们更深入地研究Scaffold代码,我们会发现它实际上是在创建一个ScaffoldLayout将创建一个SubcomposeLayout使用约束的 a,更具体地说是以下宽度和高度:

val layoutWidth = constraints.maxWidth
val layoutHeight = constraints.maxHeight

现在,如果没有为上面设置预定义值layoutWidthlayoutHeight它们将等于Int.MAX_VALUE2147483647,这是您在IllegalArgumentException(给予或接受)中看到的。

当您以正确的方式使用 Scaffold(通常作为 UI 的根)时,Android 会为您施展魔法并计算出正确的尺寸。

我的建议是,将 Scaffold 替换为另一种类型的布局,或者如果自定义布局不够:

https://developer.android.com/jetpack/compose/layouts/custom

于 2022-02-15T21:26:48.913 回答