flutter - 有什么方法可以验证底页中的文本字段吗?
问题描述
我想验证底部表中的文本字段(不是 textFormField),如果文本字段为空,当我按下保存按钮时它应该显示错误。我使用了下面的代码,代码的问题是它仅在我按下保存按钮并且应该关闭底页时才显示错误,当我打开底页时它会显示错误。有什么方法可以在按下保存按钮且不关闭底页的情况下验证文本字段。提前致谢。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: AddAddress()));
class AddNotes extends StatefulWidget {
@override
AddAddressState createState() => AddAddressState();
}
class AddAddressState extends State<AddAddress> {
final _text = TextEditingController();
bool _validate = false;
@override
void dispose(){
_text.dispose();
super.dispose();
}
bottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.85,
decoration: new BoxDecoration(
color: Colors.transparent,
),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 0),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("Address",
textScaleFactor: 1.3,
style: TextStyle(
fontSize: 18,
fontFamily: 'SFProDisplay',
fontWeight: FontWeight.w600,
fontStyle: FontStyle.normal,
letterSpacing: 0.45),
textAlign: TextAlign.center),
Container(
height: 215,
decoration: BoxDecoration(
color: Color(0x7feff1f5),
borderRadius: BorderRadius.circular(6),
),
padding: EdgeInsets.fromLTRB(17, 16, 17, 25),
child: new ConstrainedBox(
constraints: BoxConstraints(maxHeight: 200.0),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: SizedBox(
height: 175.0,
child: new TextField(
controller: _text,
maxLines: 100,
decoration: InputDecoration(
hintText: "Address",
hintStyle: TextStyle(
color: Color(0x00FFa6a9af),
),
border: InputBorder.none,
errorText: _validate ? 'Notes can\'t be Empty' : null,
),
style: TextStyle(
height: 1.4,
fontSize: 16,
color: Colors.black,
fontFamily: 'regular',
letterSpacing: 0.35,
fontWeight: FontWeight.w400,
),
),
),
),
),
)),
Container(
height: 50,
color: Colors.transparent,
padding: EdgeInsets.fromLTRB(0, 0, 188, 0),
child:ElevatedButton(
child: Text('Save'),
onPressed: (){
setState(() {
_text.text.isEmpty ? _validate = true : _validate = false;
});
},
style: ElevatedButton.styleFrom(
primary: Colors.redAccent,
onPrimary: Colors.white,
textStyle: TextStyle(
fontFamily: 'regular',
fontSize: 16.0,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),),
),
),
],
),
));
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
title: Text(
"",
style: TextStyle(color: Colors.black87, fontFamily: "regular"),
textAlign: TextAlign.left,
),
centerTitle: false,
),
body: Center(
child: TextButton(
onPressed: () {
bottomSheet();
},
child: Text("AddAddress"),
),
),
);
}
}
解决方案
正如我检查的那样,这是因为它没有正确重建,所以你必须关闭它然后打开它,这样改变的状态才会生效。
我添加了一个 changeNotifier 类来保持状态并使用提供程序包通知其侦听器,您可以查看它:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MaterialApp(home: AddAddress()));
class AddAddress extends StatefulWidget {
@override
AddAddressState createState() => AddAddressState();
}
class AddAddressState extends State<AddAddress> {
@override
void dispose(){
super.dispose();
}
bottomSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (BuildContext context) {
return ChangeNotifierProvider(create: (context) => CustomProvider(),child: CustomTextField());
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
title: Text(
"",
style: TextStyle(color: Colors.black87, fontFamily: "regular"),
textAlign: TextAlign.left,
),
centerTitle: false,
),
body: Center(
child: TextButton(
onPressed: () {
bottomSheet();
},
child: Text("AddAddress"),
),
),
);
}
}
class CustomTextField extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.85,
decoration: new BoxDecoration(
color: Colors.transparent,
),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 10, 20, 0),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("Address",
textScaleFactor: 1.3,
style: TextStyle(
fontSize: 18,
fontFamily: 'SFProDisplay',
fontWeight: FontWeight.w600,
fontStyle: FontStyle.normal,
letterSpacing: 0.45),
textAlign: TextAlign.center),
Container(
height: 215,
decoration: BoxDecoration(
color: Color(0x7feff1f5),
borderRadius: BorderRadius.circular(6),
),
padding: EdgeInsets.fromLTRB(17, 16, 17, 25),
child: new ConstrainedBox(
constraints: BoxConstraints(maxHeight: 200.0),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: Consumer<CustomProvider>(
builder: (context, item, child) => SizedBox(
height: 175.0,
child: new TextField(
controller: Provider.of<CustomProvider>(context, listen: false).text,
maxLines: 100,
decoration: InputDecoration(
hintText: "Address",
hintStyle: TextStyle(
color: Color(0x00FFa6a9af),
),
border: InputBorder.none,
errorText: item.validate ? 'Notes can\'t be Empty' : null,
),
style: TextStyle(
height: 1.4,
fontSize: 16,
color: Colors.black,
fontFamily: 'regular',
letterSpacing: 0.35,
fontWeight: FontWeight.w400,
),
),
),
),
),
),
)),
Container(
height: 50,
color: Colors.transparent,
padding: EdgeInsets.fromLTRB(0, 0, 188, 0),
child:ElevatedButton(
child: Text('Save'),
onPressed: (){
Provider.of<CustomProvider>(context, listen: false).checkValidation();
},
style: ElevatedButton.styleFrom(
primary: Colors.redAccent,
onPrimary: Colors.white,
textStyle: TextStyle(
fontFamily: 'regular',
fontSize: 16.0,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),),
),
),
],
),
));
}
}
class CustomProvider extends ChangeNotifier{
final text = TextEditingController();
bool validate = false;
void checkValidation(){
if(text.text.isEmpty){
validate = true;
}else{
validate = false;
}
notifyListeners();
}
}
推荐阅读
- kotlin - Room + LiveData 动态变化查询功能
- javascript - React:创建 onClick HOC 而不使用额外的
- java - 将 JSON 字符串转换为包含对象列表的对象 - Java
- flutter - 如何使一个集团全球可访问
- flask - Flask 无法识别静态文件夹
- php - WooCommerce 最近产品的默认超时?
- r - 加速计算 R 中庞大数据集上的 mann-kendall 测试的并行过程
- google-maps - 如何使用 Google Maps API 获取城市名称
- ios - 如何将元数据永久保存到 UIImage?
- php - 如何在 PHP 中获取 OAuth 2.0 令牌?