Jetpack撰写:自定义组件中的嵌套重量

时间:2020-09-28 15:10:37

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

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

@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) })
        }
    }
}

Here's what it looks like when it worked, before I made it into a separate component.

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

但是,似乎Row不太了解当按钮在其自身组件中时权重发生变化时如何处理按钮。显示按钮内的文本,但大小不变。这是否与RowRowScope组件上的Modifier的{​​{1}}没有利用Button的{​​{1}}有关?如果是这样,我该如何使用它?

1 个答案:

答案 0 :(得分:0)

我最终要做的基本上只是使用.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)
        }
    }
}

这真的就是那么容易。不会弄乱手动的宽度,重量或类似的东西。