代码来自这里
/**
* 颜色选择器
*/
@Composable
fun ColorPicker(onColorSelected: (Color) -> Unit) {
val screenWidth = LocalConfiguration.current.screenWidthDp.dp
val screenWidthInPx = with(LocalDensity.current) { screenWidth.toPx() }
var activeColor by remember { mutableStateOf(Red) }
val max = screenWidth - 16.dp
val min = 0.dp
val (minPx, maxPx) = with(LocalDensity.current) { min.toPx() to max.toPx() }
val dragOffset = remember { mutableStateOf(0f) }
Box(modifier = Modifier.padding(8.dp)) {
//slider
Spacer(
modifier = Modifier
.height(10.dp)
.fillMaxWidth()
.clip(RoundedCornerShape(4.dp))
.background(brush = colorMapGradient(screenWidthInPx))
.align(Alignment.Center)
.pointerInput("painter") {
detectTapGestures { offset ->
dragOffset.value = offset.x
activeColor = getActiveColor(dragOffset.value, screenWidthInPx)
onColorSelected.invoke(activeColor)
}
}
)
// draggable icon
Icon(
imageVector = Icons.Filled.FiberManualRecord,
tint = activeColor,
contentDescription = null,
modifier = Modifier
.offset { IntOffset(dragOffset.value.roundToInt(), 0) }
.border(
border = BorderStroke(4.dp, MaterialTheme.colors.onSurface),
shape = CircleShape
)
.draggable(
orientation = Orientation.Horizontal,
state = rememberDraggableState { delta ->
val newValue = dragOffset.value + delta
dragOffset.value = newValue.coerceIn(minPx, maxPx)
activeColor = getActiveColor(dragOffset.value, screenWidthInPx)
onColorSelected.invoke(activeColor)
}
)
)
}
}
fun colorMapGradient(screenWidthInPx: Float) = Brush.horizontalGradient(
colors = createColorMap(),
startX = 0f,
endX = screenWidthInPx
)
fun createColorMap(): List<Color> {
val colorList = mutableListOf<Color>()
for (i in 0..360 step (10)) {
val randomSaturation = 90 + Random.nextFloat() * 10
val randomLightness = 50 + Random.nextFloat() * 10
val hsv = AndroidColor.HSVToColor(
floatArrayOf(
i.toFloat(),
randomSaturation,
randomLightness
)
)
colorList.add(Color(hsv))
}
return colorList
}
fun getActiveColor(dragPosition: Float, screenWidth: Float): Color {
val hue = (dragPosition / screenWidth) * 360f
val randomSaturation = 90 + Random.nextFloat() * 10
val randomLightness = 50 + Random.nextFloat() * 10
return Color(
AndroidColor.HSVToColor(
floatArrayOf(
hue,
randomSaturation,
randomLightness
)
)
)
}