Home > Software design >  How to implement vertical likert scale with jetpack compose
How to implement vertical likert scale with jetpack compose

Time:01-30

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.

enter image description here

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")
    }
}

enter image description here

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)
                )
            }
        }
}

enter image description here

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)
                    )
                }
            }

enter image description here

  • Related