在 Jetpack Compose 中创建垂直滑块

Create Vertical Sliders in Jetpack Compose

我正在构建一个 Android 应用程序,需要在同一页面中创建多个垂直滑块以进行音乐均衡器调整,但我只能从官方 material 设计文档中找到水平滑块。

我尝试实现官方文档中的默认滑块并使用修改器旋转它并且它有效,但问题是我现在无法使用修改器调整高度。

https://imgur.com/a/G19PsM6

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Row(modifier =
            Modifier
                .fillMaxWidth()
                .fillMaxHeight(),
               horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
                ) {
                slider()
                slider()
                slider()
                slider()
                slider()
                slider()
                slider()

            }

        }
    }
}



@Composable
fun slider() : Int
{
    var sliderPosition by remember { mutableStateOf(0f) }

    Slider(
        modifier = Modifier
            .width(50.dp)
            .height(120.dp)
            .background(color = Color.Red)
            .wrapContentSize()
            .rotate(270F)
            .padding(start = 0.5.dp),

        value = sliderPosition,
        valueRange = 1f..10f,
        onValueChange = {sliderPosition = it}
    )

    return sliderPosition.roundToInt()
}

您旋转的滑块没有填满可用高度,因为它在旋转后得到了错误的约束。要解决此问题,您首先需要交换 widthheight 值。

接下来,Modifier.rotate不会改变视角位置,旋转后需要手动更新。要了解发生了什么,您可以运行以下代码:

Box(
    contentAlignment = Alignment.Center,
    modifier = Modifier.fillMaxSize()
) {
    Box(Modifier
        .size(100.dp, 50.dp)
        .border(width = 1.dp, color = Color.Red)
        .rotate(90f)
        .background(Color.Green))
}

它将产生以下视图:

如您所见,真实视图框架显示为红色边框,您的视图有意外偏移。

要修复它,您可以使用 Modifier.layout:您需要交换约束和结果视图大小尺寸,并恢复偏移量。

此外,我使用 Modifier.graphicsLayer 并将 transformOrigin 设置为零点,因此更容易计算 Modifier.layout 中所需的偏移量。

最后一部分,大小修饰符应该放在 Modifier.layout 之后,以便在 layout 期间获得父视图约束而不是这个静态约束。而layout应该放在旋转之后。在

中查看更多有关为什么修饰符顺序很重要的信息

滑块的最终修饰符:

Modifier
    .graphicsLayer {
        rotationZ = 270f
        transformOrigin = TransformOrigin(0f, 0f)
    }
    .layout { measurable, constraints ->
        val placeable = measurable.measure(
            Constraints(
                minWidth = constraints.minHeight,
                maxWidth = constraints.maxHeight,
                minHeight = constraints.minWidth,
                maxHeight = constraints.maxHeight,
            )
        )
        layout(placeable.height, placeable.width) {
            placeable.place(-placeable.width, 0)
        }
    }
    .width(120.dp)
    .height(50.dp)