android 组成的步骤进度条
step progress bar with android compose
目前我正在尝试找到一种简单的方法来使用这样的组合实现步骤进度条:
有人有这方面的经验吗?有没有好的图书馆?
我认为你不需要这个库,一个简单快捷的 'do it yourself' 解决方案可能是这样的:
@Composable
fun StepsProgressBar(modifier: Modifier = Modifier, numberOfSteps: Int, currentStep: Int) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically
) {
for (step in 0..numberOfSteps) {
Step(
modifier = Modifier.weight(1F),
isCompete = step < currentStep,
isCurrent = step == currentStep
)
}
}
}
@Composable
fun Step(modifier: Modifier = Modifier, isCompete: Boolean, isCurrent: Boolean) {
val color = if (isCompete || isCurrent) Color.Red else Color.LightGray
val innerCircleColor = if (isCompete) Color.Red else Color.LightGray
Box(modifier = modifier) {
//Line
Divider(
modifier = Modifier.align(Alignment.CenterStart),
color = color,
thickness = 2.dp
)
//Circle
Canvas(modifier = Modifier
.size(15.dp)
.align(Alignment.CenterEnd)
.border(
shape = CircleShape,
width = 2.dp,
color = color
),
onDraw = {
drawCircle(color = innerCircleColor)
}
)
}
}
@Preview
@Composable
fun StepsProgressBarPreview() {
val currentStep = remember { mutableStateOf(1) }
StepsProgressBar(modifier = Modifier.fillMaxWidth(), numberOfSteps = 5, currentStep = currentStep.value)
}
这将是结果:
我创建了一个采用可自定义参数的类似函数。
@Composable
fun Track(
items: Int,
brush: (from: Int) -> Brush,
modifier: Modifier = Modifier,
lineWidth: Dp = 1.dp,
pathEffect: ((from: Int) -> PathEffect?)? = null,
icon: @Composable (index: Int) -> Unit,
) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
Canvas(
modifier = Modifier
.fillMaxWidth()
.zIndex(-1f)
) {
val width = drawContext.size.width
val height = drawContext.size.height
val yOffset = height / 2
val itemWidth = width / items
var startOffset = itemWidth / 2
var endOffset = startOffset
val barWidth = lineWidth.toPx()
repeat(items - 1) {
endOffset += itemWidth
drawLine(
brush = brush.invoke(it),
start = Offset(startOffset, yOffset),
end = Offset(endOffset, yOffset),
strokeWidth = barWidth,
pathEffect = pathEffect?.invoke(it)
)
startOffset = endOffset
}
}
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically,
) {
repeat(items) { index ->
Box(
contentAlignment = Alignment.Center,
) {
icon.invoke(index)
}
}
}
}
}
目前我正在尝试找到一种简单的方法来使用这样的组合实现步骤进度条:
有人有这方面的经验吗?有没有好的图书馆?
我认为你不需要这个库,一个简单快捷的 'do it yourself' 解决方案可能是这样的:
@Composable
fun StepsProgressBar(modifier: Modifier = Modifier, numberOfSteps: Int, currentStep: Int) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically
) {
for (step in 0..numberOfSteps) {
Step(
modifier = Modifier.weight(1F),
isCompete = step < currentStep,
isCurrent = step == currentStep
)
}
}
}
@Composable
fun Step(modifier: Modifier = Modifier, isCompete: Boolean, isCurrent: Boolean) {
val color = if (isCompete || isCurrent) Color.Red else Color.LightGray
val innerCircleColor = if (isCompete) Color.Red else Color.LightGray
Box(modifier = modifier) {
//Line
Divider(
modifier = Modifier.align(Alignment.CenterStart),
color = color,
thickness = 2.dp
)
//Circle
Canvas(modifier = Modifier
.size(15.dp)
.align(Alignment.CenterEnd)
.border(
shape = CircleShape,
width = 2.dp,
color = color
),
onDraw = {
drawCircle(color = innerCircleColor)
}
)
}
}
@Preview
@Composable
fun StepsProgressBarPreview() {
val currentStep = remember { mutableStateOf(1) }
StepsProgressBar(modifier = Modifier.fillMaxWidth(), numberOfSteps = 5, currentStep = currentStep.value)
}
这将是结果:
我创建了一个采用可自定义参数的类似函数。
@Composable
fun Track(
items: Int,
brush: (from: Int) -> Brush,
modifier: Modifier = Modifier,
lineWidth: Dp = 1.dp,
pathEffect: ((from: Int) -> PathEffect?)? = null,
icon: @Composable (index: Int) -> Unit,
) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
Canvas(
modifier = Modifier
.fillMaxWidth()
.zIndex(-1f)
) {
val width = drawContext.size.width
val height = drawContext.size.height
val yOffset = height / 2
val itemWidth = width / items
var startOffset = itemWidth / 2
var endOffset = startOffset
val barWidth = lineWidth.toPx()
repeat(items - 1) {
endOffset += itemWidth
drawLine(
brush = brush.invoke(it),
start = Offset(startOffset, yOffset),
end = Offset(endOffset, yOffset),
strokeWidth = barWidth,
pathEffect = pathEffect?.invoke(it)
)
startOffset = endOffset
}
}
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically,
) {
repeat(items) { index ->
Box(
contentAlignment = Alignment.Center,
) {
icon.invoke(index)
}
}
}
}
}