在Jetpack Compose中,是否可能“缩放”任何小部件的宽度和高度?

6
我有一个Stack小部件,其中包含一个Box和一个Image。随着状态的变化,我想通过状态的值来缩放Box小部件,例如2倍。
我没有找到有关在Modifier或Box属性上缩放小部件的任何信息,因此我决定通过使用“Modifier.size”来操纵大小来响应状态更改,但这对我来说并不理想。
那么,是否支持缩放小部件,还是我应该手动操作大小属性?
-谢谢
@Composable
fun Pointer(modifier: Modifier = Modifier, state: TransitionState, onClick: () -> Unit) {
    Stack(modifier) {
        Box(
            shape = CircleShape, backgroundColor = Color.Gray.copy(alpha = .3f),
            modifier = Modifier.size(state[width])
        )
        Image(
            asset = imageResource(id = R.drawable.ic_pointer),
            modifier = Modifier
                .clickable(onClick = onClick)
        )
    }
}

1
你能否详细解释一下你在尺寸和比例方面的区别是什么意思?对于一个 Box(),一个比例会带来什么作用而一个尺寸不会吗?换言之,"is not ideal for me"是什么意思? - CommonsWare
好的,我不想关心盒子的大小或明确地保留对它的引用。我只想传递例如2,然后获得盒子的宽度/高度乘以2, 或者传递0.4并且从其任何值开始将宽度/高度乘以0.4。 - Hessam-Emami
我的意思是在Android View System中用于动画化视图的相同view.scale()函数。 - Hessam-Emami
2
一个 Box() 没有大小,除了你告诉它要绘制的大小。没有“获取盒子的宽度/高度”的方法,除非你告诉它要绘制的大小。你正在以有状态视图的方式思考,这不是 Compose 的工作方式。因此,Modifier.size() 似乎是正确的答案。“我不想关心盒子的大小或显式地保留对它的引用”——在这件事上你别无选择。 - CommonsWare
@CommonsWare 你应该把它写成一个答案,并且它应该被接受。 - Vitor Ramos
2个回答

7

Compose 1.0.0-alpha08

随着时间的流逝,新版本的Compose将重命名 'drawLayer'为'graphicsLayer',并添加了一个新的scale修饰符(在底层使用'graphicsLayer')。

因此,可组合的内容将如下所示:

@Composable
fun Pointer(scale: Float, modifier: Modifier = Modifier) {
    Box(modifier) {
        Box(
            modifier = Modifier
                .matchParentSize()
                .scale(scale)
                .background(Color.Cyan, CircleShape)
        )
        Image(
            imageVector = Icons.Filled.Done,
            modifier = Modifier
                .align(Alignment.Center)
        )
    }
}

Compose 1.0.0-alpha07(原始答案)

我相信你可以通过drawLayer修饰符实现所需的行为。例如,一个简单的组合,它显示一个可缩放的圆和一个不可缩放的图标:

@Composable
fun Pointer(scale: Float, modifier: Modifier = Modifier) {
    Box(modifier) {
        Box(
            modifier = Modifier
                .matchParentSize()
                .drawLayer(scaleX = scale, scaleY = scale)
                .background(Color.Cyan, CircleShape)
        )
        Image(
            asset = Icons.Filled.Done,
            modifier = Modifier
                .align(Alignment.Center)
        )
    }
}

使用方法:

Pointer(
    scale = 1f,
    modifier = Modifier
        .background(Color.Magenta)
        .padding(25.dp)
        .preferredSize(50.dp)
        .align(Alignment.CenterHorizontally)
)

当 scale = 1f 时

当 scale = 2f 时


2
我不想关心盒子的大小或明确地保留对它的引用。
这将是一个问题。在Compose中,像Box()这样的小部件是无状态函数。您无法询问Box()的大小 - 相反,您需要使用适当的Modifier告诉Box()它的大小。
通常,“大小”是在代码中设置的固定值或规则(例如,Modifier.size(200.dp))。只要该状态是State,Compose就知道在该状态更改时重新组合(再次调用函数),因此您应该能够使大小取决于您自己跟踪的某些状态。如果您选择这条路线,则缩放是检查当前状态值、应用比例因子并使用结果作为新状态值的问题。

非常感谢,由于整个API都是alpha版本,并且在Compose的源代码中可见大量的TODO,所以我现在会点赞你的问题,看看Compose最终会发展到何种程度。 再次感谢你的帮助。 - Hessam-Emami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接