A one-time password (OTP), a dynamic password, a one-time PIN, or OTAC, is a unique code valid for a single login session. A 4- or 6-digit code is typically sent via SMS; OTPs are central to implementing two-factor authentication.
Adding OTP support to mobile apps means creating a specialized UI input field to handle these codes.
Since Jetpack Compose is Android's modern UI toolkit, exploring how to build a custom OTP input field using BasicTextField offers valuable insights.
Custom OTP Input with Compose UI
Compose UI simplifies creating input fields. While the built-in TextField adheres to Material Design for convenience, it lacks customization flexibility. For a custom OTP input, the lower-level BasicTextField component is ideal. This offers the freedom to tailor the input field to your specific requirements.
Implementation
To create a BasicTextField that accepts only numerical input, follow these steps:
First, we must configure the keyboardOptions parameter: Set the keyboardType property within keyboardOptions to KeyboardType.NumberPassword. This ensures that the keyboard displays only digits.
Explanation
KeyboardType.NumberPassword is used instead of KeyboardType.Number to prevent the inclusion of non-numeric characters (like periods, commas, and dashes) in the input field, simplifying the user experience for scenarios like OTP entry.
The next task on our agenda is to tighten the restrictions on our input field. Since our OTP needs to consist of precisely six digits, we must ensure that the input field can only accept a maximum of six digits and prevent users from entering more than that.
To enforce this restriction, we'll need to modify our onValueChange behavior to include an additional check for the length of the new string. If the new string exceeds six characters, we won't update our otpValue. This way, any attempt by the user to input a seventh character will be disregarded.
While the initial implementation provides basic functionality, the OTP input field lacks visual clarity. To guide the user, we'll create the appearance of six distinct input boxes, enhancing usability during this crucial authorization step.
One might consider using six individual TextField elements, but this approach is overly complex and would hinder smooth cursor transitions. Instead, we'll leverage the decorationBox parameter of BasicTextField. This allows us to customize the input field's appearance extensively.
The decorationBox provides access to the innerTextField, enabling us to modify its visual representation directly. We'll replace the standard BasicTextField with a custom design tailored to the OTP format.
OTP decorationBox
The core idea is to use the decorationBox to customize the appearance of our OTP input field. In this example, we'll create six Text composables with rounded borders to display individual OTP characters.
We'll employ a Row composable with the repeat function six times to generate the six Text components. Spacers will be inserted between them to match a typical six-digit OTP format.
Additionally, we must ensure that the correct OTP digits are displayed within their corresponding Text components. We'll use the index information from the repeat function to extract the appropriate character from the input string. So, to handle cases where the input string is less than six characters, we'll pass empty strings to the unfilled Text components.
The current solution is effective, but we can enhance it with a visual indicator highlighting the active input field. Here's how:
- Determine the focused field: The index of the currently focused field corresponds to the length of the existing OTP input.
- Emphasize the field: To indicate focus visually, adjust the border of the active field. Increase its width and/or darken its color to clearly distinguish it.
Key Considerations:
- Visual consistency: Ensure the highlighting style aligns with your overall UI design.
- Accessibility: Consider users with visual impairments and provide alternative cues if necessary.
It's done!
Final Words
Our goal was to demonstrate how to create a custom OTP input field. We hope you found the explanations helpful and can apply these concepts to tailor your OTP input solutions.
Please find the complete and refactored source code in this GitHub repository
Top comments (0)