在 Jetpack Compose 中实现 iOS 风格输入框

要在 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 风格特点实现

  1. 圆角设计

    kotlin 复制代码
    shape = RoundedCornerShape(10.dp)
  2. 边框颜色

    kotlin 复制代码
    borderColor = if (focused) Color(0xFF007AFF) else Color(0xFFC7C7CC)
  3. 占位符样式

    kotlin 复制代码
    color = Color(0xFFC7C7CC)
  4. 清除按钮

    kotlin 复制代码
    Icon(Icons.Default.Close, contentDescription = "清除")
  5. 分段列表样式

    kotlin 复制代码
    Divider(color = Color(0xFFC6C6C8), thickness = 0.5.dp)

这些组件可以根据你的具体需求进一步定制,调整颜色、尺寸和动画效果,以达到更接近 iOS 设计风格的效果。

相关推荐
恋猫de小郭1 小时前
Flutter 发布官方 Skills ,Flutter 在 AI 领域再添一助力
android·前端·flutter
Kapaseker7 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴7 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭17 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab18 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe1 天前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋1 天前
Android 协程时代,Handler 应该退休了吗?
android