我需要一些帮助。我的任务是选择位置和地址并提交。但由于某些原因,_addPointKey.currentState.validate((总是给出false。
我有一个用于获取地址的TextFormField,一个位置预览容器,一个打开google_map_location_picker的按钮,最后还有一个提交数据的按钮。所有这些字段都是在具有_addPointKey键的表单中声明的。
表单验证确实有效,即如果字段为空,则会以红色显示字段不能为空。但是,我在提交整个表单数据时仍然有一些问题。textFormField变为null。
我使用了google_map_location_picker包来挑选位置。有人能帮忙吗?
提前谢谢。
final GlobalKey<FormState> _addPointKey = GlobalKey<FormState>();
Map<String, dynamic> formData = {
"address": null,
};
Widget _addressField() {
return Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Address of the Collection Center",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Theme.of(context).primaryColor),
),
SizedBox(
height: 10,
),
TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
maxLines: 4,
validator: (String value) {
if (value.isEmpty) {
return "Address is required";
}
return '';
},
onChanged: (String value) {
formData["address"] = value;
},
onSaved: (String value) {
formData["address"] = value;
},
),
],
),
);
}
Widget _locationPreview() {
return (_pickedLocation != null)
? Container(
height: 300,
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: Theme.of(context).accentColor,
)),
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: _pickedLocation.latLng,
zoom: 14.4746,
),
markers: Set.from(newMarkers),
),
)
: Container(
child: Text(
"Location is required.",
style: TextStyle(
color: Colors.red,
),
),
);
}
Widget _locationButton() {
return RaisedButton(
color: Theme.of(context).accentColor,
onPressed: () async {
LocationResult result = await showLocationPicker(
context,
< API key>,
initialCenter: LatLng(31.1975844, 29.9598339),
myLocationButtonEnabled: true,
layersButtonEnabled: true,
);
setState(() {
_pickedLocation = result;
_addPointKey.currentState.save();
newMarkers.add(Marker(
markerId: MarkerId("newId"),
draggable: false,
position: _pickedLocation.latLng,
onTap: null,
));
});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.location_on,
color: Colors.white,
),
Text(
(_pickedLocation == null) ? 'Locate on Map' : 'Change Location',
style: TextStyle(color: Colors.white),
),
],
),
);
}
Widget _addLocationButton() {
return ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget widget, MainModel model) {
return model.managingCenter
? CircularProgressIndicator()
: InkWell(
onTap: () async {
print(_addPointKey.currentState.validate());
if (!_addPointKey.currentState.validate() ||
_pickedLocation == null) {
print(formData);
return;
}
_addPointKey.currentState.save();
Map<String, dynamic> successInfo =
await model.addCenter(model.token, formData);
if (successInfo["success"]) {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => FutureBuilder(
future: model.fetchCenter(model.token),
builder: (context, authResultSnapShot) {
return authResultSnapShot.connectionState ==
ConnectionState.waiting
? SplashScreen()
: CollectionPoints(model);
})));
} else {
print("Something went wrong");
}
},
child: Container(
height: 50,
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.shade200,
offset: Offset(2, 4),
blurRadius: 5,
spreadRadius: 2)
],
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Color(0xfffbb448), Color(0xfff7892b)]),
),
padding: const EdgeInsets.all(10.0),
child: Text('Add the Location',
style: TextStyle(fontSize: 20, color: Colors.white)),
),
);
});
}
void _addPoint() {
showBottomSheet(
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.all(10),
child: Form(
key: _addPointKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
_addressField(),
_locationPreview(),
_locationButton(),
_addLocationButton()
],
),
),
),
);
});
}
在TextFormField验证器函数中,您必须返回null,这表明字段具有正确的值并且没有错误。如果返回null以外的任何值,则表明该字段的值无效,我已经共享了验证器函数的更正代码。
TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
fillColor: Color(0xfff3f3f4),
filled: true),
maxLines: 4,
validator: (String value) {
if (value.isEmpty) {
return "Address is required";
}
// return ''; this is causing you the error you must return null
return null; // this is correct
},
onChanged: (String value) {
formData["address"] = value;
},
onSaved: (String value) {
formData["address"] = value;
},
),
在flutter上创建确认密码的一种更简单的方法。"showSnackBar"底部弹出窗口,提醒用户出现错误。[1] :https://i.stack.imgur.com/zjXLd.png
var _password = '';
var _confirmPassword = '';
// this will called 'onTap'
void signUpUser() async {
if (_password != _confirmPassword){ // you can add your statements here
showSnackBar(context,
"Password does not match. Please re-type again.");
} else {
FirebaseAuthMethods(FirebaseAuth.instance).signUpWithEmail(
email: emailController.text,
password: passwordController.text,
context: context,
);
}
}
// Insert inside your build()
// to you password field.
child: TextFormField(
controller: passwordController,
obscureText: true,
onChanged: (value) {
_password = value;
},
// to your confirm password field.
child: TextFormField(
controller: confirmPasswordController,
obscureText: true,
onChanged: (value) {
_confirmPassword = value;
},
// add this to your Sign-up button
onTap: signUpUser,