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

Jetpack Compose中BasicTextField聚焦时标签定位异常问题求助

Jetpack Compose BasicTextField标签聚焦异常问题修复

问题描述

使用Jetpack Compose的BasicTextField和BasicSecureTextField搭配TextFieldDefaults.DecorationBox时,点击文本框获取焦点后,标签无法正常过渡到顶部位置,只有输入文本后才会恢复正常的标签状态。

问题原因

核心问题在于每次组件重组时都会创建新的MutableInteractionSource实例:
你在decorator lambda内部使用remember { MutableInteractionSource() },而decorator会在BasicTextField每次重组时执行,导致新的交互源实例被创建,DecorationBox无法持续跟踪焦点状态,进而触发错误的标签动画逻辑。

修复方案

  1. 将MutableInteractionSource提升到组件函数级别,用remember创建,确保整个组件生命周期内实例唯一,让DecorationBox能正确跟踪焦点变化
  2. 修正BasicSecureTextField的visualTransformation,使用PasswordVisualTransformation()实现密码隐藏效果(原代码用VisualTransformation.None会导致密码明文显示)

修改后的代码

MainActivity.kt

package com.example.baisctextfieldexample

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicSecureTextField
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.foundation.text.input.PasswordVisualTransformation
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import com.example.baisctextfieldexample.ui.theme.BaiscTextFieldExampleTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            BaiscTextFieldExampleTheme {
                val stateOne = rememberTextFieldState()
                val stateTwo = rememberTextFieldState()
                BasicTextFieldExamples(stateOne, stateTwo)
            }
        }
    }

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun BasicTextFieldExamples(stateOne: TextFieldState, stateTwo: TextFieldState) {
        // 提升交互源到函数级别,确保实例唯一
        val usernameInteractionSource = remember { MutableInteractionSource() }
        val passwordInteractionSource = remember { MutableInteractionSource() }

        Column(
            Modifier
                .fillMaxSize()
                .padding(50.dp)
        ) {
            BasicTextField(
                state = stateOne,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(56.dp),
                keyboardOptions = KeyboardOptions(
                    keyboardType = KeyboardType.Email,
                    imeAction = ImeAction.Next
                ),
                decorator = {
                    TextFieldDefaults.DecorationBox(
                        value = stateOne.text.toString(),
                        innerTextField = it,
                        enabled = true,
                        singleLine = true,
                        visualTransformation = VisualTransformation.None,
                        label = { Text("Username") },
                        placeholder = { Text("Username Placeholder") },
                        // 使用外部创建的交互源
                        interactionSource = usernameInteractionSource
                    )
                }
            )
            BasicSecureTextField(
                state = stateTwo,
                modifier = Modifier
                    .fillMaxWidth()
                    .height(56.dp),
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
                decorator = {
                    TextFieldDefaults.DecorationBox(
                        value = stateTwo.text.toString(),
                        innerTextField = it,
                        enabled = true,
                        singleLine = true,
                        // 修正密码可视化转换
                        visualTransformation = PasswordVisualTransformation(),
                        label = { Text("Password") },
                        placeholder = { Text("Password Placeholder") },
                        // 使用外部创建的交互源
                        interactionSource = passwordInteractionSource
                    )
                }
            )
        }
    }
}

额外说明

当前使用的Material3版本(1.4.0-alpha06)本身不存在该问题,完全是代码写法导致的状态跟踪错误。修复后,点击文本框获取焦点时,标签会正常过渡到顶部,无需输入文本即可触发正确的动画。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 21:18:17