【问题标题】:Jetpack Compose: Nested weight in custom componentJetpack Compose:自定义组件中的嵌套权重
【发布时间】:2020-09-28 15:10:37
【问题描述】:

假设我有一个按钮,当第一次点击时会展开以显示文本,并在第二次点击时执行操作——因此在执行操作之前充当一种确认。

@Compose
fun ExpandingConfirmButton(onConfirm: () -> Unit) {
    // expanded state of the button
    val (expanded, setExpanded) = remember { mutableStateOf(false) }
    // animating weight. make the button larger when it is tapped once
    val weight = animate(if (expanded) 10F else 2F)

    Button(onClick = {
        // only fire the action after two taps
        if(expanded) {
            onConfirm()
        }
        setExpanded(!expanded)    
    }) {
        Icon(Icons.Dfault.Delete)
        // only show the text if the button has already been clicked once,
        //  otherwise just show the icon
        if(expanded) {
            Text(text = "Delete", softWrap = false)
        }
    }
}

我会像这样使用那个按钮:

@Composable
fun PersonList(people: List<Person>) {
    // some database service exposed via an ambient
    val dataService = DataService.current

    LazyColumnFor(items = people) {
        Row() {
            Text(text = it.firstName, modifier = Modifier.weight(10F))
            // on the first tap, the button should take up half of the row
            ExpandingConfirmButton(onConfirm = { dataService.deletePerson(it) })
        }
    }
}

这一切看起来都很简单。实际上,在我将 ExpandingConfirmButton 拆分为它自己的组件之前,将 Button() 它直接包装在我的 PersonList 组件中之前,它可以完美地工作。

然而,似乎Row 并不完全知道当权重在它自己的组件内时如何处理按钮。按钮内的文本显示,但大小不变。这是否与RowRowScope 没有被ExpandingConfirmButton 内的Button 组件上的Modifier 使用有关?如果是这样,我该如何使用它?

【问题讨论】:

  • 我进行了一些实验,但没有找到解决方案,但我会使用 ConstraintLayout 创建这个 Composable。为展开创建一个垂直指南,为默认创建一个,并将 start.linkTo() 的目标更改为相应的指南。

标签: android android-jetpack android-jetpack-compose


【解决方案1】:

我最终做的基本上只是使用.animateContentSize() 修饰符。

@Compose
fun ExpandingConfirmButton(onConfirm: () -> Unit) {
    // expanded state of the button
    val (expanded, setExpanded) = remember { mutableStateOf(false) }

    Button(
        modifier = Modifier.animateContentSize(), // do this
        onClick = {
        // only fire the action after two taps
        if(expanded) {
            onConfirm()
        }
        setExpanded(!expanded)    
    }) {
        Icon(Icons.Default.Delete)
        // only show the text if the button has already been clicked once,
        //  otherwise just show the icon
        if(expanded) {
            Text(text = "Delete", softWrap = false)
        }
    }
}

真的就是这么简单。不会乱用手动宽度、重量或类似的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    相关资源
    最近更新 更多