I am attempting to create a vertical Likert scale using Jetpack Compose. Each field should include a vertical line that extends beyond its boundaries. I have also included an image to give an idea of what I am trying to achieve.
CodePudding user response:
You can use a Box
to put a Canvas
on top of the row items.
Something like:
Box(Modifier.fillMaxWidth()){
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(16.dp)
){
for (i in 1..5) {
RoundedIem()
}
}
Canvas(modifier = Modifier.fillMaxWidth()){
val height = 60.dp.toPx() //height of items
val verticalOffset = 76.dp.toPx() //height vertical padding
val strokeWidthCircle =1f
val radiusCircle = 30f
for (i in 0..4) {
//Inner white circle
drawCircle(
color = White,
radius = radiusCircle,
center = Offset(size.width-100f,height/2 i*verticalOffset),
)
//Stroke circle
drawCircle(
color = DarkGray,
radius = radiusCircle,
center = Offset(size.width-100f,height/2 i*verticalOffset),
style = Stroke(width = strokeWidthCircle)
)
//vertical line
if (i < 4) {
val startY = height/2 i*verticalOffset radiusCircle strokeWidthCircle
drawLine(
color = DarkGray,
start = Offset(
x = size.width-100f,
y = startY),
end = Offset(
x = size.width-100f,
y = startY verticalOffset - strokeWidthCircle),
strokeWidth = strokeWidthCircle
)
}
}
}
}
@Composable
fun RoundedIem(){
Row(
modifier= Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth()
.height(60.dp)
.clip(RoundedCornerShape(8.dp))
.background(LightGray.copy(alpha = 0.5f))
.padding(start = 10.dp),
verticalAlignment = Alignment.CenterVertically,
){
Text("Option")
}
}
If you want to add also an icon in the circle you can draw the icon in the Canvas
using:
//Icon
val painter = rememberVectorPainter(Icons.Default.Done)
Canvas(modifier = Modifier.fillMaxWidth()){
//previous code
val iconSize = 60f
//circle center - iconSize/2
translate(
left = size.width-100f - iconSize/2,
top = height/2 i*verticalOffset - iconSize/2
) {
with(painter) {
draw(
size = Size(iconSize,iconSize),//painter.intrinsicSize,
colorFilter = ColorFilter.tint(Color.Blue)
)
}
}
}
With a background:
drawCircle(
color = Blue,
radius = radiusCircle-8f,
center = Offset(size.width-100f,height/2 i*verticalOffset),
)
//circle center - iconSize/2
val iconSize = 48f
translate(
left = size.width-100f- iconSize/2,
top = height/2 i*verticalOffset -iconSize/2
) {
with(painter) {
draw(
size = Size(iconSize,iconSize),//painter.intrinsicSize,
colorFilter = ColorFilter.tint(Color.White)
)
}
}