【问题标题】:Change TextField background Color based on the TextField state根据 TextField 状态更改 TextField 背景颜色
【发布时间】:2021-06-12 05:07:21
【问题描述】:

我目前正在尝试实现一个 TextField,它应该根据文本字段的状态(未聚焦、聚焦、错误)更改背景颜色。

我试图通过使用仅管理是否选择 TextField 的 List 来实现这一点。我使用 GestureDetector 来设置该值。但这似乎太老套了,不能成为一个好的解决方案,尤其是因为点击 TextField 并不是集中它的唯一方法。

此时,我希望有一种方法可以获取 TextField 小部件用于显示适当边框样式的相同信息。但我不确定是否可以访问此信息。非常感谢您提供有关如何执行此操作的提示。

我也在想我可以为此使用 FocusScope,但我找不到在单个 TextFormField 上调用 .hasFocus 的方法,因为它只显示是否选择了整个表单中的一个 TextFormField,而不是选择哪一个.

谢谢!

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    您可以在FocusScope 中使用FocusNodeFocus 来实现类似的效果。 TextField 本身使用FocusNode 来确定它是否有焦点,然后在焦点状态改变时动画颜色变化。这是一个使用FocusBuilder 仅重建改变焦点的TextFields 的示例实现:

    https://dartpad.dev/8488f470b166e4235b64d3ba568b6ba6?null_safety=true

    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    /// This is the main application widget.
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      static const String _title = 'Flutter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: _title,
          home: Scaffold(
            appBar: AppBar(title: const Text(_title)),
            body: const MyStatelessWidget(),
          ),
        );
      }
    }
    /// This is the private State class that goes with MyStatefulWidget.
    class MyStatelessWidget extends StatelessWidget {
      
      const MyStatelessWidget();
      
      @override
      Widget build(BuildContext context) {
        return FocusScope(
          debugLabel: 'Scope',
          autofocus: true,
          child: Form(
            child: Column(
              children: [
                Focus(
                  debugLabel: 'TextField1',
                  child: Builder(
                    builder: (BuildContext context) {
                      final FocusNode focusNode = Focus.of(context);
                      final bool hasFocus = focusNode.hasFocus;
                      return TextField(
                        decoration: InputDecoration(
                          fillColor: hasFocus ? Colors.green : Colors.white,
                          filled: true
                        )
                      );
                    },
                  ),
                ),
                Focus(
                  debugLabel: 'TextField2',
                  child: Builder(
                    builder: (BuildContext context) {
                      final FocusNode focusNode = Focus.of(context);
                      final bool hasFocus = focusNode.hasFocus;
                      return TextField(
                        decoration: InputDecoration(
                          fillColor: hasFocus ? Colors.green : Colors.white,
                          filled: true
                        )
                      );
                    }
                  )
                )
              ],
            ),
          ),
        );
      }
    }
    

    您当然也可以直接使用FocusNode。为此,您可能必须将TextFields 包装到StatefulWidget 中,然后将侦听器添加到使用的FocusNode,以便在焦点更改时触发重建(使用setState)。但请注意,您需要管理此FocusNode 的生命周期。引用文档:

    管理 FocusNode 意味着管理它的生命周期,监听焦点的变化,并在需要时重新设置它的父节点,以保持焦点层次结构与小部件层次结构同步。这个小部件为您完成所有这些事情。如果您不使用 Focus 小部件并且需要自己进行操作,请参阅 FocusNode 了解有关节点管理的详细信息。

    https://api.flutter.dev/flutter/widgets/Focus-class.html

    【讨论】:

    • 与 OP 问题无关,但是,您如何使用这种方法将焦点转移到下一个文本字段?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多