Flutter (颤振)TextFormField在焦点上更改标签颜色

Flutter (颤振)TextFormField在焦点上更改标签颜色,flutter,dart,form-fields,Flutter,Dart,Form Fields,聚焦时,我试图更改标签文本的颜色。我可以更改文本颜色,但不能在聚焦时更改 我尝试了所有提示文本颜色和标签文本颜色,但没有任何帮助 容器( 填充:从LTRB(15,10,15,0)开始的边缘设置, 子项:TextFormField( 光标颜色:颜色。浅绿色, 键盘类型:TextInputType.phone, 装饰:输入装饰( labelText:'电话号码', hintText:'输入电话号码', 聚焦顺序:大纲输入边框( 边界边( 颜色:颜色。浅绿色 ) ), 边框:大纲输入边框( borde

聚焦时,我试图更改标签文本的颜色。我可以更改文本颜色,但不能在聚焦时更改

我尝试了所有提示文本颜色和标签文本颜色,但没有任何帮助

容器(
填充:从LTRB(15,10,15,0)开始的边缘设置,
子项:TextFormField(
光标颜色:颜色。浅绿色,
键盘类型:TextInputType.phone,
装饰:输入装饰(
labelText:'电话号码',
hintText:'输入电话号码',
聚焦顺序:大纲输入边框(
边界边(
颜色:颜色。浅绿色
)
),
边框:大纲输入边框(
borderSide:borderSide()
),
)
),
),
以下是正在发生的事情的图像:


您需要有一种方法来确定其焦点状态,然后根据该状态为其颜色创建一个条件。这就是
focusNode
将很有帮助的地方。在小部件创建之外构造一个新的
FocusNode
,将其用作
TextFormField
中的
FocusNode
属性。然后在
TextStyle
属性的
TextFormField
中添加如下内容:

FocusNode myFocusNode=new FocusNode();
...
返回TextFormField(
focusNode:myFocusNode,
装饰:输入装饰(
labelText:“测试”,
标签样式:文本样式(
颜色:myFocusNode.hasFocus?颜色。蓝色:颜色。黑色
)
),
);
编辑:只是一个简短的说明,您可能需要确保它位于
StatefulWidget
中,然后向您创建的
focusNode
添加一个侦听器,并在该
focusNode
上的任何事件上调用
setState
。否则,您将看不到任何更改

总结 你可能想看看食谱

基本上,我们必须:

  • 创建一个
    FocusNode
    属性
  • 向其添加初始化和处置
  • 将其添加到
    TextFormField
  • TextFormField
    的每次点击中添加焦点请求
  • 1.创建
    FocusNode
    属性
    类CustomTextFormFieldState扩展状态{
    FocusNode _FocusNode;
    ...
    
    2.添加初始化和处置
    @覆盖
    void initState(){
    super.initState();
    _focusNode=focusNode();
    }
    @凌驾
    无效处置(){
    _focusNode.dispose();
    super.dispose();
    }
    
    3.将其添加到
    TextFormField
    @覆盖
    小部件构建(构建上下文){
    返回TextFormField(
    focusNode:_focusNode,
    ...
    
    4.在
    TextFormField
    不要忘记使用
    setState

    void\u requestFocus(){
    设置状态(){
    FocusScope.of(上下文).requestFocus(_focusNode);
    });
    }
    
    将该方法添加到
    TextFormField
    onTap
    属性:

    @覆盖
    小部件构建(构建上下文){
    返回TextFormField(
    focusNode:_focusNode,
    onTap:_requestFocus,
    ...
    
    快速解决方案是从小部件
    MaterialApp
    主题更改
    primarySwatch
    。唯一的缺点是需要
    材质颜色

    更新 正如在评论中提到的,较新版本的flifter使用不同的逻辑来获得颜色

    Color\u getActiveColor(主题数据){
    如果(聚焦){
    返回主题data.colorScheme.primary;
    }
    返回主题data.hintColor;
    }
    

    您现在需要从
    colorScheme
    进行设置

    ThemeData.dark().copyWith(
    colorScheme:colorScheme.dark(
    原色:activeColor,
    ),
    )
    

    原始答案 在挖掘了用于确定标签颜色的
    InputDecorator
    的源代码之后,我找到了以下内容

    TextStyle\u获取浮动标签样式(主题数据主题数据){
    最终颜色=装饰。错误文本!=null
    ?装饰.errorStyle?颜色?主题数据.errorColor
    :_getActiveColor(主题数据);
    final TextStyle style=themeData.textTheme.subtitle1.merge(widget.baseStyle);
    返回样式
    .copyWith(颜色:装饰。启用?颜色:主题数据。禁用颜色)
    .合并(装饰、标签样式);
    }
    颜色\u getActiveColor(主题数据主题数据){
    如果(聚焦){
    开关(主题数据、亮度){
    外壳亮度.暗:
    返回themeData.accentColor;
    外壳亮度.亮度:
    返回motedata.primaryColor;
    }
    }
    返回主题data.hintColor;
    }
    
    简而言之,要更改标签颜色,请将
    primaryColor
    浅主题设置为浅主题,或将
    accentColor
    设置为深主题

    另一个提示:要在不对焦时更改标签颜色,请设置
    hintColor

    ThemeData.dark().copyWith(
    原色:颜色。红色,
    颜色:颜色。白色,
    颜色:颜色。粉红色,
    )
    
    当文本字段处于焦点且文本字段错误时(由于未遵循验证而导致),也可以使用labelStyle


    您可以使用
    主题
    包装文本字段,并将原色设置为标签颜色所需的任何颜色

     return Theme( // 1) wrap with theme widget
       data: Theme.of(context).copyWith(primaryColor: //2) color you want here)
       child: TextFormField(
         focusNode: myFocusNode,
         decoration: InputDecoration(
        labelText: 'test',      
        ),
       ),
      );
    

    “装饰”中有一个“标签样式”,就像:

    labelText: 'Description',
    labelStyle: TextStyle(
      color: Colors.lightBlueAccent,
    )),
    

    我用Focus小部件解决了这个问题。首先,我为每个字段定义了一个颜色变量:

    final _lowColor = Colors.amber[50];   // use your own colors
    final _highColor = Colors.amber[200];
    
    Color _field1Color = _lowColor;
    Color _field2Color = _lowColor;
    ...
    
    然后,我用焦点小部件包装每个TextFormField,并更改fieldColor:

    child: Focus(
      onFocusChange: (hasFocus) {
        setState(() => _field1Color = hasFocus ? _highColor : _lowColor);
      },
      child: TextFormField(
        ...
          color: _field1Color,
        ...
        ),
      ), 
    ),
    

    如果您想更改原色,只需定义并添加Widget MaterialApp的
    primaryColor

    const appPrimaryColor = Color(0xFF746DF7);
    
    主题数据主题(){ 返回主题数据( 脚手架背景颜色:颜色。白色, fontFamily:“国际米兰”, appBarTheme:appBarTheme(), textTheme:textTheme(), inputDecorationTheme:inputDecorationTheme(), 视密度:视密度.adaptiveP
    const appPrimaryColor = Color(0xFF746DF7);
    
    ThemeData theme() {
      return ThemeData(
        scaffoldBackgroundColor: Colors.white,
        fontFamily: "Inter",
        appBarTheme: appBarTheme(),
        textTheme: textTheme(),
        inputDecorationTheme: inputDecorationTheme(),
        visualDensity: VisualDensity.adaptivePlatformDensity,
        primaryColor: appPrimaryColor // <------ HERE
      );
    }
    
    
    MaterialApp(
       title: 'Flutter Demo',
       theme: theme(), // <------ HERE
       home: SplashScreen(),
       routes: routes,
    )
    
    class InputEmail extends StatefulWidget {
      @override
      _InputEmailState createState() => _InputEmailState();
    }
    
    class _InputEmailState extends State<InputEmail> {
      Color _colorText = Colors.black54;
    
      @override
      Widget build(BuildContext context) {
        const _defaultColor = Colors.black54;
        const _focusColor = Colors.purple;
    
        return Container(
          padding: EdgeInsets.symmetric(vertical: 15),
          child: Focus(
            onFocusChange: (hasFocus) {
              // When you focus on input email, you need to notify the color change into the widget.
              setState(() => _colorText = hasFocus ? _focusColor : _defaultColor);
            },
            child: TextField(
              // Validate input Email
              keyboardType: TextInputType.emailAddress,
              
              decoration: InputDecoration(
                hintText: 'example@domain.com',
                labelText: 'Email',
                labelStyle: TextStyle(color: _colorText),
                
                // Default Color underline
                enabledBorder: UnderlineInputBorder(
                  borderSide: BorderSide(color: Colors.black26),
                ),
    
                // Focus Color underline
                focusedBorder: UnderlineInputBorder(
                  borderSide: BorderSide(color: Colors.purple),
                ),
                icon: Icon(
                  Icons.mail,
                  color: Colors.deepPurpleAccent,
                ),
              ),
            ),
          ),
        );
      }
    }