如何在Android Compose中实现OTP验证码输入布局?
Jetpack Compose OTP输入布局实现方案
以下实现完全基于原生Compose组件开发,无需引入第三方依赖,效果和需求示例完全匹配:
核心OTP输入组件代码
@Composable fun OtpInputField( otpLength: Int = 4, onOtpComplete: (String) -> Unit ) { // 存储OTP输入内容 var otpValue by remember { mutableStateOf("") } // 控制输入框焦点 val focusRequester = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current BasicTextField( value = otpValue, onValueChange = { newValue -> // 仅允许输入数字,限制最大输入长度 if (newValue.length <= otpLength && newValue.all { it.isDigit() }) { otpValue = newValue // 输入完成后自动收起键盘触发回调 if (newValue.length == otpLength) { keyboardController?.hide() onOtpComplete(newValue) } } }, modifier = Modifier .fillMaxWidth() .focusRequester(focusRequester), keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.NumberPassword, imeAction = ImeAction.Done ), keyboardActions = KeyboardActions( onDone = { keyboardController?.hide() if (otpValue.length == otpLength) { onOtpComplete(otpValue) } } ), // 自定义OTP格子布局,隐藏原生输入框样式 decorationBox = { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly ) { repeat(otpLength) { index -> val isCurrentInputPos = otpValue.length == index val displayChar = otpValue.getOrNull(index)?.toString() ?: "" Box( modifier = Modifier .size(48.dp) .border( width = if (isCurrentInputPos) 2.dp else 1.dp, color = if (isCurrentInputPos) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant, shape = RoundedCornerShape(8.dp) ), contentAlignment = Alignment.Center ) { if (displayChar.isNotEmpty()) { Text( text = displayChar, style = MaterialTheme.typography.headlineSmall, color = MaterialTheme.colorScheme.onSurface ) } else if (isCurrentInputPos) { // 当前输入位显示闪烁光标 Box( modifier = Modifier .width(2.dp) .height(24.dp) .background(MaterialTheme.colorScheme.primary) .animateEnterExit( enter = fadeIn(animationSpec = infiniteRepeatable(tween(500), RepeatMode.Reverse)), exit = fadeOut() ) ) } } } } } ) // 组件加载后自动请求焦点弹出数字键盘 LaunchedEffect(Unit) { focusRequester.requestFocus() } }
组件使用方法
直接在登录页对应位置调用即可:
OtpInputField( otpLength = 4, onOtpComplete = { otpCode -> // 此处执行OTP校验逻辑 loginViewModel.verifyOtp(otpCode) } )
可自定义调整项
- 可修改
otpLength参数适配6位等不同长度的OTP需求 - 可自行调整OTP格子的尺寸、圆角、边框颜色、文本样式匹配设计稿
- 原生支持系统粘贴板OTP自动填充,无需额外开发适配
内容的提问来源于stack exchange,提问作者Gautam Hazarika
相关产品推荐
相关产品推荐

