OTPView

OTPView is a highly costumizable OTP view made in the Jetpack compose UI.

Usage:

CircleOtpView is a sample composable that calls the OtpView which actually draws the view.

@Composable
fun CircleOtpView() {
    var otpStr by remember {
        mutableStateOf("")
    }
    var isError by remember {
        mutableStateOf(false)
    }
    OtpView(
        modifier = Modifier.width(240.dp),
        otpStr = otpStr,
        isError = isError,
        shape = PinShape.CircleShape,
        numberOfFields = 4
    ) { otp ->
        otpStr = otp
        if (otpStr.length == 4) {
            // Completely filled
            isError = otpStr != "1234"
            if (isError) {
                otpStr = ""
            }
        }

        if (isError && otpStr.isNotEmpty()) {
            isError = false
        }
    }
}

PinShape

Different shapes can be created using PinShape, which is an interface and contains only one method drawShape(size: Size): Path. Implementor class has to implement this method and return a Path which needs to be drawn with the given size in the method param.

class LineShape(private val strokeWidth: Float): PinShape {
      override fun drawShape(size: Size): Path {
         return Path().apply {
             reset()
             addRect(Rect(0f, size.height - (strokeWidth / 2), size.width, size.height))
             close()
         }
      }
}

PinShape is passed as a parameter in the OtpView composable and it is used in the PinField Modifier’s drawBehind {}.

@Composable
fun PinField(
    modifier = Modifier,
    shape: PinShape,
    .
    .
    .
) {
    Box(
        modifier = modifier
            .width(width)
            .fillMaxHeight()
            .drawBehind {
                drawPath(
                    path = shape.drawShape(this.size),
                    .
                    .
                )
            }
            .clickable {
                onClick(index)
            },
    ) {
        ....
    }
}

Courtesy:

  1. Idea of using single TextField and displaying different view for the pins: https://github.com/ch8n/Compose-OtpView

  2. Custom shapes https://juliensalvi.medium.com/custom-shape-with-jetpack-compose-1cb48a991d42

GitHub

View Github