You need to enable JavaScript to run this app. Jetpack Compose 密码输入框如何动态切换visualTransformation实现显隐
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose 密码输入框如何动态切换visualTransformation实现显隐

切换密码明文/密文失效的核心原因
  • 组件未维护密码可见性的可观察状态,缺少能触发Compose重组的状态源
  • 密码展示图标的点击回调为空,点击操作没有产生任何状态更新
  • 静态传入的visualTransformation参数不会随用户操作动态切换值,无法触发输入框的视觉更新
  • 原有代码存在modifier重复应用的小问题:外部传入的修饰符同时作用于外层Box和内部BasicTextField,会造成样式叠加异常
具体实现调整方案
  1. 在组件内部新增记忆化的密码可见性状态,状态值变更时会自动触发Compose重组
  2. 给密码展示图标的点击事件绑定状态切换逻辑,点击时反转可见性布尔值
  3. 根据当前可见性状态、输入框类型动态生成对应的visualTransformation:密码密文场景用PasswordVisualTransformation(),明文场景用VisualTransformation.None
  4. 可根据可见性状态动态切换眼睛图标的展示资源,优化交互反馈
调整后可正常运行的代码
fun UserInputText(
    keyboardType: KeyboardType = KeyboardType.Text,
    onTextChanged: (TextFieldValue) -> Unit,
    textFieldValue: TextFieldValue,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    borderColor: Color = editTextBorderColor,
    keyboardShown: Boolean,
    onTextFieldFocused: (Boolean) -> Unit,
    focusState: Boolean,
    placeholder: String = "",
    modifier: Modifier = Modifier
) {
    // 新增密码可见性的可观察状态
    var isPasswordVisible by remember { mutableStateOf(false) }
    Box(
        modifier = modifier.border(
            width = 2.dp,
            color = borderColor,
            shape = RoundedCornerShape(16.dp)
        )
    ) {
        var lastFocusState by remember { mutableStateOf(FocusState.Inactive) }
        val focusRequester = FocusRequester()
        val focusRequesterModifier = Modifier.focusRequester(focusRequester)

        BasicTextField(
            value = textFieldValue,
            onValueChange = { onTextChanged(it) },
            // 修正原有modifier重复应用的问题,去掉多余的外层modifier引用
            modifier = Modifier
                .focus()
                .then(focusRequesterModifier)
                .align(Alignment.TopStart)
                .padding(16.dp) // 给输入框加内边距避免文字贴边
                .focusObserver { state ->
                    if (lastFocusState != state) {
                        onTextFieldFocused(state == FocusState.Active)
                    }
                    lastFocusState = state
                },
            keyboardOptions = KeyboardOptions(
                keyboardType = keyboardType,
                imeAction = ImeAction.Send
            ),
            // 动态根据输入类型和可见性状态生成视觉变换
            visualTransformation = if (keyboardType == KeyboardType.Password) {
                if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation()
            } else visualTransformation,
            maxLines = 1,
            cursorColor = inputTextColor,
            textStyle = MaterialTheme.typography.body1.copy(color = inputTextColor)
        )
        if(keyboardType == KeyboardType.Password) {
            Image(
                // 可根据状态动态切换图标资源
                vectorResource(
                    id = if (isPasswordVisible) R.drawable.ic_eye_open else R.drawable.ic_eye_closed
                ), 
                modifier = Modifier
                    .align(Alignment.TopEnd)
                    .padding(end = 16.dp, top = 16.dp)
                    .clickable {
                        // 绑定点击事件切换可见性
                        isPasswordVisible = !isPasswordVisible
                    }
            )
        }
    }
}

内容的提问来源于stack exchange,提问作者clouddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.13 08:18:12