如何在Jetpack Compose中实现字母卡片式自定义TextField?
在Jetpack Compose中实现字母卡片式输入框
当然可以实现这种每个输入字母对应独立卡片、自动跳转焦点的效果,不需要依赖官方特殊组件,通过Compose基础API就能完成。先看你提到的效果示意图:

核心实现思路
- 状态管理:用状态列表存储每个卡片的输入内容,同时跟踪当前活跃的卡片索引。
- 布局与样式:横向排列自定义卡片容器,每个容器内嵌入轻量输入组件,限制单字符输入。
- 自动焦点跳转:利用
FocusRequester管理每个输入框的焦点,输入完成后自动切换到下一个卡片。
完整代码示例
@Composable fun CardTextField(count: Int = 4) { // 存储每个卡片的输入内容 val inputs = remember { mutableStateListOf<String>().apply { repeat(count) { add("") } } } // 每个卡片对应的焦点请求器 val focusRequesters = remember { List(count) { FocusRequester() } } // 当前活跃的卡片索引 var currentIndex by remember { mutableIntStateOf(0) } Row(horizontalArrangement = Arrangement.SpaceAround, modifier = Modifier.padding(16.dp)) { repeat(count) { index -> val isFocused = currentIndex == index // 自定义卡片容器 Box( modifier = Modifier .size(60.dp) .focusRequester(focusRequesters[index]) .border( width = 2.dp, color = if (isFocused) Color(0xFF2196F3) else Color.Gray, shape = RoundedCornerShape(8.dp) ), contentAlignment = Alignment.Center ) { BasicTextField( value = inputs[index], onValueChange = { newValue -> if (newValue.length <= 1) { inputs[index] = newValue // 输入完成且不是最后一个卡片时,跳转到下一个 if (newValue.isNotEmpty() && index < count - 1) { currentIndex = index + 1 focusRequesters[index + 1].requestFocus() } } }, modifier = Modifier.fillMaxSize(), singleLine = true, textStyle = TextStyle(fontSize = 24.sp, textAlign = TextAlign.Center), keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Text), decorationBox = { innerTextField -> // 自定义输入框显示逻辑 when { isFocused && inputs[index].isEmpty() -> innerTextField() // 显示光标 inputs[index].isNotEmpty() -> Text( text = inputs[index], style = TextStyle(fontSize = 24.sp) ) else -> Text( text = "_", style = TextStyle(fontSize = 24.sp, color = Color.Gray) ) } } ) } } } // 初始请求第一个卡片的焦点 LaunchedEffect(Unit) { focusRequesters[0].requestFocus() } }
关键细节说明
BasicTextField的优势:相比TextField,它允许完全自定义输入框的装饰逻辑,比如隐藏默认边框、自定义空状态提示。- 焦点控制:
FocusRequester确保输入完成后焦点能准确切换到下一个卡片,提升用户体验。 - 扩展性:可以轻松修改卡片数量、样式(比如调整圆角、边框色),或者添加输入限制(比如仅允许数字、大写字母)。
内容的提问来源于stack exchange,提问作者voodookiidoo
相关产品推荐
相关产品推荐

