You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中BasicTextField粘贴框位置异常修复求助

问题:Jetpack Compose 1.4.2中BasicTextField粘贴框位置异常修复

我在Jetpack Compose 1.4.2中实现了一个自定义BasicTextField,粘贴复制的文本时,粘贴框出现在左上角异常位置,求修复方法。

更新:附上CustomTextField实现代码:

@Composable
fun CustomTextField(
    value: String,
    placeholder: String,
    enabled: Boolean = true,
    loading: Boolean = false,
    keyboardType: KeyboardType,
    update: ((String) -> Unit)? = null
) {

    var focus by remember {
        mutableStateOf(false)
    }

    BasicTextField(
        value = value,
        onValueChange = { new ->
            update?.let {
                it(new)
            }
        },
        cursorBrush = SolidColor(Blue),
        textStyle = MaterialTheme.typography.bodyMedium,
        decorationBox = { inner ->
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(
                        start = 16.dp,
                        end = 16.dp
                    ),
                contentAlignment = Alignment.CenterStart
            ) {
                if (value.isEmpty()) {
                    Text(
                        text = placeholder,
                        style = MaterialTheme.typography.bodyMedium,
                        color = Blue_2
                    )
                } else {
                    Row(
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.SpaceBetween,
                        modifier = Modifier
                            .fillMaxWidth()
                    ) {
                        inner()

                        if (loading) {
                            Box(
                                modifier = Modifier
                                    .padding(vertical = 24.dp, horizontal = 16.dp)
                                    .size(16.dp)
                            ) {
                                CircularProgressIndicator(
                                    color = Blue_6
                                )
                            }
                        }
                    }
                }
            }
        },
        visualTransformation = if (keyboardType == KeyboardType.Password) PasswordVisualTransformation() else VisualTransformation.None,
        keyboardOptions = KeyboardOptions(
            keyboardType = keyboardType
        ),
        enabled = enabled,
        modifier = Modifier
            .fillMaxWidth()
            .shadow(
                elevation = if (focus) 15.dp else 7.5.dp,
                shape = RoundedCornerShape(16.dp),
                clip = false,
                ambientColor = Blue_6,
                spotColor = Blue_6
            )
            .background(
                if (focus) Focused else Not_Focused,
                RoundedCornerShape(16.dp)
            )
            .height(60.dp)
            .onFocusChanged {
                focus = it.hasFocus
            },
        singleLine = true
    )
}

问题截图:
粘贴框位置异常截图


解决方案

粘贴框位置异常的核心原因是自定义decorationBox时,没有保持输入区域(inner())布局的稳定性,导致系统无法正确计算粘贴菜单的定位基准。修复步骤如下:

  • 不要根据value是否为空切换输入区域的容器结构,让inner()始终作为输入载体存在,placeholder和加载指示器直接叠加在其上方。
  • 确保布局约束(如padding、高度)直接传递给inner()所在的容器,维持输入区域的布局树稳定。

修改后的decorationBox代码示例:

decorationBox = { inner ->
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(start = 16.dp, end = 16.dp)
            .height(60.dp),
        contentAlignment = Alignment.CenterStart
    ) {
        // 始终渲染inner,保证输入区域布局稳定
        inner()
        
        // placeholder叠加在输入区域上方,仅value为空时显示
        if (value.isEmpty()) {
            Text(
                text = placeholder,
                style = MaterialTheme.typography.bodyMedium,
                color = Blue_2
            )
        }
        
        // 加载指示器通过align定位到右侧
        if (loading) {
            Box(
                modifier = Modifier
                    .align(Alignment.CenterEnd)
                    .padding(horizontal = 16.dp)
                    .size(16.dp)
            ) {
                CircularProgressIndicator(color = Blue_6)
            }
        }
    }
}

额外说明:

  • 原代码中切换容器的逻辑会导致输入区域的布局频繁重组,不仅引发粘贴菜单位置异常,还会增加不必要的性能开销。
  • 保持inner()的布局稳定性后,系统能基于输入区域的正确约束计算光标和粘贴菜单的位置,解决异常问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:03:10