根据TextField状态更改TextField背景颜色

3

我目前正在尝试实现一个文本框,根据文本框的状态(未聚焦、聚焦、错误)来改变背景颜色。

我尝试使用一个列表来管理文本框是否被选中。我使用GestureDetector来设置该值。但这似乎太过hacky,不是一个好的解决方案,特别是因为点击文本框并不是唯一让它聚焦的方式。

此时,我希望有一种方法可以获得TextField Widget用于显示适当边框样式所使用的相同信息。但我不确定是否可以访问此信息。如果您有关于如何获取此信息的提示,将不胜感激。

我还考虑过使用FocusScope,但我找不到一种方法来调用单个TextFormField的.hasFocus,因为它只向我显示整个表单中是否选择了一个TextFormField,而不是哪个。

谢谢!

1个回答

4
您可以在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 的问题无关,但是,您如何使用这种方法将焦点转移到下一个文本字段? - Martin Berger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接