我是 Flutter 开发的新手。我创建了一个自定义文本字段组件,我将在我的应用程序中使用它。我正在共享代码,任何人都可以帮助我如何根据文本字段验证更改文本字段边框线颜色。我将将此文本字段重复用于电子邮件、密码、金额....等
代码:
class MyInputWidget extends StatefulWidget {
final FocusNode focusNode;
final String hint;
final TextEditingController controller;
final VoidCallback onEditCompleted;
final show;
const MyInputWidget(
{@required this.focusNode,
@required this.hint,
@required this.controller,
@required this.show,
this.onEditCompleted})
: assert(focusNode != null),
assert(hint != null),
assert(controller != null),
assert(show != null);
@override
_MyInputWidgetState createState() => _MyInputWidgetState();
}
class _MyInputWidgetState extends State<MyInputWidget> {
TextEditingController _controller;
FocusNode _focusNode;
Color focusBorderColor;
_MyInputWidgetState();
@override
void initState() {
super.initState();
focusBorderColor = Colors.blue;
if (widget.controller != null)
_controller = widget.controller;
else
_controller = TextEditingController();
if (widget.focusNode != null)
_focusNode = widget.focusNode;
else
_focusNode = FocusNode();
_focusNode.addListener(() {});
}
void listener() {
if (_focusNode.hasFocus) {
print("focus");
} else {
print("nofocus");
}
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
const SizedBox(
width: 1.0,
),
Expanded(
child: Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
textField(),
if (widget.controller.text.isNotEmpty)
IconButton(
padding: const EdgeInsets.only(right: 3),
icon: const Icon(Icons.clear),
onPressed: () {
setState(() {
widget.controller.clear();
});
})
else
Container(
height: 0.0,
)
]),
),
],
),
],
);
}
@override
void dispose() {
super.dispose();
_controller?.dispose();
_focusNode?.dispose();
}
Widget textField() {
return TextField(
focusNode: _focusNode,
controller: _controller,
decoration: InputDecoration(
hintText: widget.hint,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: focusBorderColor, width: 3),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: focusBorderColor, width: 3),
),
),
onSubmitted: (item) {
FocusScope.of(context).requestFocus(FocusNode());
},
onEditingComplete: () {
//print(widget.show);
},
);
}
}
主要飞镖:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
FocusNode emailFocusNode = FocusNode();
bool show = false;
final TextEditingController emailController = TextEditingController();
@override
void initState() {
// TODO: implement initState
super.initState();
emailNotifier();
}
emailNotifier() {
emailFocusNode.addListener(() {
if (!emailFocusNode.hasFocus) {
if (emailController.text.isNotEmpty) {
ValidationHelper().validateEmail(emailController.text).then((result) {
if (!result) {
show = true;
//print("Notifier false");
} else {
show = false;
// print("Notifier true");
}
setState(() {});
});
}
} else {
//print("Test field is empty");
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 35),
child: MyInputWidget(
focusNode: emailFocusNode,
hint: "Enter Email",
controller: emailController,
show: show,
onEditCompleted: () {
},
),
),
Visibility(child: AlertWidget(), visible: show)
],
),
),
);
}
}
class AlertWidget extends StatelessWidget {
const AlertWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text("Alert"),
color: Colors.redAccent,
);
}
}
如果验证失败意味着我必须将文本字段边框线颜色更改为红色,否则线条颜色将为蓝色。我试图发送布尔状态,但我做不到。