英文:
How to change TextFormField background color when focus?
问题
我有一个TextFormField
,我希望当用户按下字段开始输入时,将背景颜色从#EFEFEF更改为白色,以下是我的自定义小部件:
class TextFieldWidget extends StatelessWidget {
final TextEditingController controller;
final bool isEmail;
const TextFieldWidget({
Key? key,
required this.controller,
required this.isEmail,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text,
obscureText: !isEmail,
controller: controller,
decoration: InputDecoration(
hintText: isEmail ? '输入您的电子邮件' : '输入您的密码',
filled: true,
fillColor: const Color(0xffefefef),
focusColor: Colors.white,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5)),
prefixIcon: Icon(
isEmail ? Icons.email : Icons.lock,
color: const Color(0xFF1273EB),
),
),
validator: (value) {
if (isEmail) {
if (value!.isEmpty) {
return '电子邮件不能为空';
} else if (!value.contains('@')) {
return '请输入有效的电子邮件地址';
}
} else if (!isEmail) {
if (value!.isEmpty) {
return '密码不能为空';
} else if (value.length < 6) {
return '密码必须至少为6个字符长';
}
}
return null;
},
);
}
}
当屏幕显示时,背景颜色为#EFEFEF,但当我点击文本字段时,它不会变成另一种颜色(在我的情况下是白色)。
英文:
I have a TextFormField
and I want to change the background color from #EFEFEF to white when the user presses on the field to type, here is my custom widget:
class TextFieldWidget extends StatelessWidget {
final TextEditingController controller;
final bool isEmail;
const TextFieldWidget({
Key? key,
required this.controller,
required this.isEmail,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextFormField(
keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text,
obscureText: !isEmail,
controller: controller,
decoration: InputDecoration(
hintText: isEmail ? 'Enter your email' : 'Enter your password',
filled: true,
fillColor: const Color(0xffefefef),
focusColor: Colors.white,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5)),
prefixIcon: Icon(
isEmail ? Icons.email : Icons.lock,
color: const Color(0xFF1273EB),
),
),
validator: (value) {
if (isEmail) {
if (value!.isEmpty) {
return 'Email can\'t be empty';
} else if (!value.contains('@')) {
return 'Please enter a valid email address';
}
} else if (!isEmail) {
if (value!.isEmpty) {
return 'Password can\'t be empty';
} else if (value.length < 6) {
return 'Password must be at least 6 characters long';
}
}
return null;
},
);
}
}
When the screen displays I have the #EFEFEF color, but when I press on the text field it doesn't turn to another color (white in my case).
答案1
得分: 2
更改文本字段的背景颜色一旦获得焦点,您可以使用一个FocusNode
并检查它是否hasFocus
:
首先,在您的自定义小部件中接受一个focusnode
:
class TextFieldWidget extends StatefulWidget {
final TextEditingController controller;
final bool isEmail;
final FocusNode focusNode;
const TextFieldWidget({
Key? key,
required this.controller,
required this.isEmail,
required this.focusNode,
}) : super(key: key);
然后,在自定义小部件的initState
中添加一个监听器来在获得焦点时更新状态:
@override
void initState() {
super.initState();
widget.focusNode.addListener(() {
setState(() {});
});
}
并且在您的TextField中:
decoration: InputDecoration(
fillColor: widget.focusNode.hasFocus ? Color(0xffefefef) : Colors.grey,
这是一个完整可运行的代码片段:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final _focusNode = FocusNode();
final _textController = TextEditingController();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'focus node',
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: TextFieldWidget(
controller: _textController,
focusNode: _focusNode,
isEmail: false,
),
),
),
);
}
}
class TextFieldWidget extends StatefulWidget {
final TextEditingController controller;
final bool isEmail;
final FocusNode focusNode;
const TextFieldWidget({
Key? key,
required this.controller,
required this.isEmail,
required this.focusNode,
}) : super(key: key);
@override
State<TextFieldWidget> createState() => _TextFieldWidgetState();
}
class _TextFieldWidgetState extends State<TextFieldWidget> {
@override
Widget build(BuildContext context) {
return TextFormField(
focusNode: widget.focusNode,
keyboardType:
widget.isEmail ? TextInputType.emailAddress : TextInputType.text,
obscureText: !widget.isEmail,
controller: widget.controller,
decoration: InputDecoration(
fillColor: widget.focusNode.hasFocus ? Color(0xffefefef) : Colors.grey,
hintText: widget.isEmail ? 'Enter your email' : 'Enter your password',
filled: true,
focusColor: Colors.white,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5)),
prefixIcon: Icon(
widget.isEmail ? Icons.email : Icons.lock,
color: const Color(0xFF1273EB),
),
),
validator: (value) {
if (widget.isEmail) {
if (value!.isEmpty) {
return 'Email can\'t be empty';
} else if (!value.contains('@')) {
return 'Please enter a valid email address';
}
} else if (!widget.isEmail) {
if (value!.isEmpty) {
return 'Password can\'t be empty';
} else if (value.length < 6) {
return 'Password must be at least 6 characters long';
}
}
return null;
},
);
}
@override
void initState() {
super.initState();
widget.focusNode.addListener(() {
print('focusNode.hasFocus: ${widget.focusNode.hasFocus}');
setState(() {});
});
}
}
另请参阅
英文:
To change the background color of the textfield once it has focus, you can use a FocusNode
and check whether it hasFocus
:
First, accept a focusnode
in your custom widget:
class TextFieldWidget extends StatefulWidget {
final TextEditingController controller;
final bool isEmail;
final FocusNode focusNode;
const TextFieldWidget({
Key? key,
required this.controller,
required this.isEmail,
required this.focusNode,
}) : super(key: key);
then, in the custom widgets initState
add a listener the update the state once there's focus:
@override
void initState() {
super.initState();
widget.focusNode.addListener(() {
setState(() {});
});
}
and in your TextFied:
decoration: InputDecoration(
fillColor: widget.focusNode.hasFocus ? Color(0xffefefef) : Colors.grey,
Here's a complete runnable snippet:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
final _focusNode = FocusNode();
final _textController = TextEditingController();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'focus node',
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: TextFieldWidget(
controller: _textController,
focusNode: _focusNode,
isEmail: false,
),
),
),
);
}
}
class TextFieldWidget extends StatefulWidget {
final TextEditingController controller;
final bool isEmail;
final FocusNode focusNode;
const TextFieldWidget({
Key? key,
required this.controller,
required this.isEmail,
required this.focusNode,
}) : super(key: key);
@override
State<TextFieldWidget> createState() => _TextFieldWidgetState();
}
class _TextFieldWidgetState extends State<TextFieldWidget> {
@override
Widget build(BuildContext context) {
return TextFormField(
focusNode: widget.focusNode,
keyboardType:
widget.isEmail ? TextInputType.emailAddress : TextInputType.text,
obscureText: !widget.isEmail,
controller: widget.controller,
decoration: InputDecoration(
fillColor: widget.focusNode.hasFocus ? Color(0xffefefef) : Colors.grey,
hintText: widget.isEmail ? 'Enter your email' : 'Enter your password',
filled: true,
focusColor: Colors.white,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(5)),
prefixIcon: Icon(
widget.isEmail ? Icons.email : Icons.lock,
color: const Color(0xFF1273EB),
),
),
validator: (value) {
if (widget.isEmail) {
if (value!.isEmpty) {
return 'Email can\'t be empty';
} else if (!value.contains('@')) {
return 'Please enter a valid email address';
}
} else if (!widget.isEmail) {
if (value!.isEmpty) {
return 'Password can\'t be empty';
} else if (value.length < 6) {
return 'Password must be at least 6 characters long';
}
}
return null;
},
);
}
@override
void initState() {
super.initState();
widget.focusNode.addListener(() {
print('focusNode.hasFocus: ${widget.focusNode.hasFocus}');
setState(() {});
});
}
}
See also
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论