要在 Android Compose 中模仿 iOS 风格的输入框,我们需要关注几个关键特点:简洁的边框、圆角设计、特定的交互效果等。以下是完整的实现方案:
1. 基础 iOS 风格输入框
kotlin
@Composable
fun IosStyleTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
label: String? = null,
placeholder: String? = null
) {
Column(modifier = modifier) {
label?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
color = Color.Gray,
modifier = Modifier.padding(bottom = 4.dp)
)
}
Box(
modifier = Modifier
.fillMaxWidth()
.background(
color = Color.White,
shape = RoundedCornerShape(10.dp)
)
.border(
width = 1.dp,
color = Color(0xFFC7C7CC),
shape = RoundedCornerShape(10.dp)
)
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.fillMaxWidth(),
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = Color.Black
),
singleLine = true,
decorationBox = { innerTextField ->
if (value.isEmpty() && placeholder != null) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium.copy(
color = Color(0xFFC7C7CC)
)
)
}
innerTextField()
}
)
}
}
}
// 使用示例
var text by remember { mutableStateOf("") }
IosStyleTextField(
value = text,
onValueChange = { text = it },
label = "用户名",
placeholder = "请输入用户名",
modifier = Modifier.padding(16.dp)
)
2. 带清除按钮的 iOS 风格输入框
kotlin
@Composable
fun IosStyleTextFieldWithClear(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
label: String? = null,
placeholder: String? = null
) {
Column(modifier = modifier) {
label?.let {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
color = Color.Gray,
modifier = Modifier.padding(bottom = 4.dp)
)
}
Box(
modifier = Modifier
.fillMaxWidth()
.background(
color = Color.White,
shape = RoundedCornerShape(10.dp)
)
.border(
width = 1.dp,
color = if (value.isNotEmpty()) Color(0xFF007AFF) else Color(0xFFC7C7CC),
shape = RoundedCornerShape(10.dp)
)
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.weight(1f),
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = Color.Black
),
singleLine = true,
decorationBox = { innerTextField ->
if (value.isEmpty() && placeholder != null) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium.copy(
color = Color(0xFFC7C7CC))
)
}
innerTextField()
}
)
if (value.isNotEmpty()) {
IconButton(
onClick = { onValueChange("") },
modifier = Modifier.size(20.dp)
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "清除",
tint = Color(0xFFC7C7CC),
modifier = Modifier.size(16.dp)
)
}
}
}
}
}
}
3. 搜索框样式
kotlin
@Composable
fun IosStyleSearchField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
placeholder: String = "搜索"
) {
Box(
modifier = modifier
.fillMaxWidth()
.height(36.dp)
.background(
color = Color(0xFFF2F2F7),
shape = RoundedCornerShape(10.dp)
)
.padding(horizontal = 8.dp),
contentAlignment = Alignment.CenterStart
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth()
) {
Icon(
imageVector = Icons.Default.Search,
contentDescription = "搜索",
tint = Color(0xFF8E8E93),
modifier = Modifier.size(16.dp)
.padding(end = 4.dp)
)
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.weight(1f),
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = Color.Black,
fontSize = 14.sp
),
singleLine = true,
decorationBox = { innerTextField ->
if (value.isEmpty()) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium.copy(
color = Color(0xFF8E8E93),
fontSize = 14.sp
)
)
}
innerTextField()
}
)
if (value.isNotEmpty()) {
IconButton(
onClick = { onValueChange("") },
modifier = Modifier.size(20.dp)
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = "清除",
tint = Color(0xFF8E8E93),
modifier = Modifier.size(16.dp)
)
}
}
}
}
}
4. 带分段的 iOS 风格表单
kotlin
@Composable
fun IosStyleForm(
items: List<Pair<String, @Composable () -> Unit>>,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier
.background(Color.White)
.clip(RoundedCornerShape(10.dp))
) {
items.forEachIndexed { index, (title, content) ->
Column {
if (index > 0) {
Divider(
color = Color(0xFFC6C6C8),
thickness = 0.5.dp,
modifier = Modifier.padding(horizontal = 16.dp)
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = title,
style = MaterialTheme.typography.bodyMedium.copy(
color = Color.Black
),
modifier = Modifier.weight(1f)
)
Box(modifier = Modifier.weight(1f)) {
content()
}
}
}
}
}
}
// 使用示例
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
IosStyleForm(
items = listOf(
"账号" to {
BasicTextField(
value = username,
onValueChange = { username = it },
modifier = Modifier.fillMaxWidth(),
textStyle = MaterialTheme.typography.bodyMedium.copy(
textAlign = TextAlign.End
)
)
},
"密码" to {
BasicTextField(
value = password,
onValueChange = { password = it },
modifier = Modifier.fillMaxWidth(),
textStyle = MaterialTheme.typography.bodyMedium.copy(
textAlign = TextAlign.End
),
visualTransformation = PasswordVisualTransformation()
)
}
),
modifier = Modifier.padding(16.dp)
)
5. 动画效果增强
kotlin
@Composable
fun AnimatedIosTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
label: String,
placeholder: String
) {
val animatedBorderColor by animateColorAsState(
targetValue = if (value.isNotEmpty()) Color(0xFF007AFF) else Color(0xFFC7C7CC),
label = "borderColorAnimation"
)
Column(modifier = modifier) {
Text(
text = label,
style = MaterialTheme.typography.bodyMedium,
color = Color.Gray,
modifier = Modifier.padding(bottom = 4.dp)
)
Box(
modifier = Modifier
.fillMaxWidth()
.background(
color = Color.White,
shape = RoundedCornerShape(10.dp)
)
.border(
width = 1.dp,
color = animatedBorderColor,
shape = RoundedCornerShape(10.dp)
)
.padding(horizontal = 16.dp, vertical = 12.dp)
) {
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.fillMaxWidth(),
textStyle = MaterialTheme.typography.bodyMedium.copy(
color = Color.Black
),
singleLine = true,
decorationBox = { innerTextField ->
Box {
if (value.isEmpty()) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium.copy(
color = Color(0xFFC7C7CC))
)
}
innerTextField()
}
}
)
}
}
}
关键 iOS 风格特点实现
-
圆角设计:
kotlinshape = RoundedCornerShape(10.dp)
-
边框颜色:
kotlinborderColor = if (focused) Color(0xFF007AFF) else Color(0xFFC7C7CC)
-
占位符样式:
kotlincolor = Color(0xFFC7C7CC)
-
清除按钮:
kotlinIcon(Icons.Default.Close, contentDescription = "清除")
-
分段列表样式:
kotlinDivider(color = Color(0xFFC6C6C8), thickness = 0.5.dp)
这些组件可以根据你的具体需求进一步定制,调整颜色、尺寸和动画效果,以达到更接近 iOS 设计风格的效果。