在 Jetpack Compose 中创建垂直滑块
Create Vertical Sliders in Jetpack Compose
我正在构建一个 Android 应用程序,需要在同一页面中创建多个垂直滑块以进行音乐均衡器调整,但我只能从官方 material 设计文档中找到水平滑块。
我尝试实现官方文档中的默认滑块并使用修改器旋转它并且它有效,但问题是我现在无法使用修改器调整高度。
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()
}
您旋转的滑块没有填满可用高度,因为它在旋转后得到了错误的约束。要解决此问题,您首先需要交换 width
和 height
值。
接下来,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)
我正在构建一个 Android 应用程序,需要在同一页面中创建多个垂直滑块以进行音乐均衡器调整,但我只能从官方 material 设计文档中找到水平滑块。
我尝试实现官方文档中的默认滑块并使用修改器旋转它并且它有效,但问题是我现在无法使用修改器调整高度。
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()
}
您旋转的滑块没有填满可用高度,因为它在旋转后得到了错误的约束。要解决此问题,您首先需要交换 width
和 height
值。
接下来,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)