【问题标题】:Is it possible to "Scale" width and height any widget in jetpack compose?是否可以在 jetpack compose 中“缩放”任何小部件的宽度和高度?
【发布时间】:2020-09-27 21:03:13
【问题描述】:

我有一个 Stack 小部件,其中包含一个 Box 和一个 Image。 随着状态的变化,我想按状态具有的任何值缩放 Box 小部件,例如 2 倍。

我找不到任何关于在 Modifier 或 Box 属性上缩放小部件的信息,所以我决定通过使用“Modifier.size”来操纵大小来对状态变化做出反应,这对我来说并不理想。

那么是否支持缩放小部件或者我应该手动使用 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)
        )
    }
}

【问题讨论】:

  • 您能否进一步解释一下您所说的大小和规模之间的区别是什么意思?特别是对于Box(),比例尺会做什么而尺寸不会? IOW,“不适合我”是什么意思?
  • 好的,我不想关心盒子的大小或明确保留对它的引用。我只想传递例如 2,然后将框的宽度/高度乘以 2,或者传递 0.4 并从它具有的任何值中获取宽度/高度乘以 0.4。
  • 我的意思与我们在 Android 视图系统中用于动画视图的 view.scale() 完全相同
  • A Box() 没有大小,除了你告诉它要绘制的大小。没有“获取盒子的宽度/高度”,除了你告诉它绘制的内容。您正在考虑有状态的视图,但这不是 Compose 的工作方式。所以,Modifier.size() 似乎是正确的答案。 “我不想关心盒子的大小或明确保留对它的引用”——在这件事上你别无选择。
  • @CommonsWare 你应该把它写成答案,它应该是被接受的。

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


【解决方案1】:

编写 1.0.0-alpha08

随着时间的推移,有一个新的 compose 版本,它将 renames '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)
        )
    }
}

撰写 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)
)

When scale = 1f

When scale = 2f

【讨论】:

    【解决方案2】:

    我不想关心盒子的大小或明确保留对它的引用

    这将是一个问题。在 Compose 中,像 Box() 这样的小部件是无状态函数。您不能问Box() 它有多大——相反,您需要告诉Box() 它有多大,使用合适的Modifier

    通常,“它有多大”是在代码中设置的固定值或规则(例如,Modifier.size(200.dp))。您应该能够使大小取决于您自己跟踪的某个状态,只要该状态是 State,因此 Compose 知道在 State 更改时重新组合(再次调用您的函数)。如果你走这条路,那么缩放就是检查当前的State 值,应用你的缩放因子,并将结果用于新的State 值。

    【讨论】:

    • 非常感谢,因为整个 API 都是 alpha 版,并且在 Compose 的源代码中可以看到大量的 TODO,所以我现在将投票支持您的问题,看看 Compose 的最终结果。再次感谢您的帮助
    猜你喜欢
    • 2021-07-13
    • 2021-10-25
    • 1970-01-01
    • 2023-02-07
    • 2022-07-26
    • 2011-04-09
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多