我如何解决 createState 函数...返回旧的或无效的状态实例?
How can I solve createState function for ... returned an old or invalid state instance?
每当我在两个或多个表单之间滚动时,我总是收到此错误,当我更改此行时错误已解决:_SiteFormState createState() => state;到 _SiteFormState createState() => new _SiteFormState;
但我想保留表单验证的状态,我该如何实现?
这是我的代码:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:xperience/models/site.dart';
import 'package:xperience/models/category.dart';
import 'package:string_validator/string_validator.dart';
typedef OnDelete();
class SiteForm extends StatefulWidget {
final ManageSiteModel site;
_SiteFormState state = new _SiteFormState();
final OnDelete onDelete;
SiteForm({Key key, this.site, this.onDelete}) : super(key: key);
@override
_SiteFormState createState() => state;
bool isValid() => state.validate();
}
class _SiteFormState extends State<SiteForm> {
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
final form = new GlobalKey<FormState>();
bool status=false;
List<bool>statuses=new List<bool>();
static List<String> _dropdownItems = ["Adventures and
Games","Beaches","Mountains","Hikes","Waterfalls and Lakes","Road Trips","Camps"];
String _dropdownValue= _dropdownItems[0];
List<Category>categories=[new Category(false,null),new Category(false,null),new
Category(false,null),new Category(false,null)];
String _errorText='';
TextEditingController _text = new TextEditingController();
bool _validate = false;
var regex=new RegExp("([A-Za-z]+[0-9]|[0-9]+[A-Za-z])[A-Za-z0-9]*");
@override
Widget build(BuildContext context) {
for(int i=0;i<4;i++){
statuses.add(false);
}
widget.site.categoryName=_dropdownValue;
return Container(
padding: EdgeInsets.all(16),
child: Material(
elevation: 1,
clipBehavior: Clip.antiAlias,
borderRadius: BorderRadius.circular(8),
child: Form(
key: form,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AppBar(
leading: Icon(Icons.location_on),
elevation: 0,
title: Text('Xsite'),
backgroundColor: Colors.blueGrey,
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: widget.onDelete,
)
],
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, top: 16),
child: TextFormField(
onChanged: (String value) {
setState(() {
if(value.length==0){
categories[0].filled=false;
categories[0].error="This field is required";
widget.site.name = "";
}
else{
categories[0].filled=true;
categories[0].error=null;
widget.site.name = value;
}
});
},
decoration: InputDecoration(
errorText: categories[0].error,
labelText: 'Site Name*',
hintText: "Enter the name of a specific place",
// errorText: statuses[0] ? 'Value Can\'t Be Empty' : null,
icon: Icon(Icons.add_location),
isDense: true,
),
),
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 9),
child: TextFormField(
onChanged: (String value) {
setState(() {
if(isAlpha(value)) {
categories[1].filled=true;
categories[1].error=null;
widget.site.country = value;
}
else if(value.length==0){
categories[1].filled=false;
categories[1].error="This field is required";
widget.site.country = "";
}
else{
categories[1].filled=false;
categories[1].error="Only contain alphabets";
widget.site.country = "";
}
});
},
decoration: InputDecoration(
labelText: 'Country*',
hintText: 'Enter the country of the site',
icon: Icon(Icons.my_location),
isDense: true,
errorText: categories[1].error,
),
),
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 9),
child: TextFormField(
decoration: InputDecoration(
labelText: 'City*',
hintText: 'Enter the City of the site',
icon: Icon(Icons.location_city),
isDense: true,
errorText: categories[2].error,
//errorText: statuses[1] ? 'Value Can\'t Be Empty' : null,
),
onChanged: (String value) {
setState(() {
if(isAlpha(value)) {
categories[2].filled=true;
categories[2].error=null;
widget.site.city = value;
}
else if(value.length==0){
categories[2].filled=false;
categories[2].error="This field is required";
widget.site.city = "";
}
else{
categories[2].filled=false;
categories[2].error="Only contain alphabets";
widget.site.city = "";
}
});
},
),
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: TextFormField(
validator: (val) =>
inrange(widget.site.mapAddress) ? null : 'Address is invalid',
decoration: InputDecoration(
labelText: 'Google maps address',
hintText: 'E.g: 24.658154, 26.225756',
icon: Icon(Icons.map),
isDense: true,
errorText: categories[3].error,
),
onChanged: (String value){
setState(() {
if(!inrange(value)) {
categories[3].filled = false;
categories[3].error = 'Wrong format of map address';
widget.site.mapAddress = "";
}
else{
categories[3].filled=true;
categories[3].error=null;
widget.site.mapAddress = value;
}
});
},
),
),
Padding(
padding: EdgeInsets.only(left: 15.0, right: 0, bottom: 11),
child:Row(children: <Widget>[
Icon(Icons.category,color: Colors.grey,),
Text(' Category of Site',style: TextStyle(color: Colors.blue,fontSize: 15.0),)
]
)
),
],
),
),
),
);
}
///form validator
bool validate() {
bool val=true;
if(widget.site.city=="" || !isAlpha(widget.site.city)){
setState(() {
categories[2].error="This field is required";
val=false;
});
}
if(widget.site.country=="" || !isAlpha(widget.site.country)){
setState(() {
categories[1].error="This field is required";
val=false;
});
}
if(widget.site.name=="" || !isAlpha(widget.site.name)){
setState(() {
categories[0].error="This field is required";
val=false;
});
}
for(int i=0;i<categories.length;i++){
if(!categories[i].filled){
val=false;
}
}
if(!val){
return false;
}
print(val);
print("formaaaaaaaatology");
return true;
}
bool inrange(String maps){
int count=0;
if(maps.length==0){
return true;
}
for (int i=0;i<maps.length;i++){
if(maps[i]==','){
count++;
}
}
if(count==0 || count>1){
return false;
}
double min=double.parse(maps.substring(0,maps.indexOf(',')));
double max=double.parse(maps.substring(maps.indexOf(',')+1,maps.length));
if(!(min>=-90 && min<=90)){
return false;
}
else if(!(max>=-180 && max<=80)){
return false;
}
else {
return true;
};
}
validateCountry(val){
if(val.length>0 ) {
print("koukeyeee");
setState(() {
this.widget.site.country="kousaay";
});
return null;
}
return 'This field is required';
}
}
这是在其他页面调用表单验证的代码:
bool onSave() {
if (sites.length > 0) {
var allValid = true;
sites.forEach((form) => allValid=form.validate() );
if (allValid) {
var data = sites.map((it) => it.site).toList();
Navigator.push(context,MaterialPageRoute(builder: (context) => ConnectorBiography()),);
return true;
}
else{
print("noot valid");
return false;
}
else{
Text("failed");
}
}
我通过将 class 编辑为 :
解决了我的问题
class SiteForm extends StatefulWidget {
final ManageSiteModel site;
final OnDelete onDelete;
//adding new to this will remove the forms.
var state= _SiteFormState();
SiteForm({Key key, this.site, this.onDelete}) : super(key: key);
@override
_SiteFormState createState(){
return this.state=new _SiteFormState();
}
bool isValid() => this.state.validate();
}
每当我在两个或多个表单之间滚动时,我总是收到此错误,当我更改此行时错误已解决:_SiteFormState createState() => state;到 _SiteFormState createState() => new _SiteFormState; 但我想保留表单验证的状态,我该如何实现?
这是我的代码:
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:xperience/models/site.dart';
import 'package:xperience/models/category.dart';
import 'package:string_validator/string_validator.dart';
typedef OnDelete();
class SiteForm extends StatefulWidget {
final ManageSiteModel site;
_SiteFormState state = new _SiteFormState();
final OnDelete onDelete;
SiteForm({Key key, this.site, this.onDelete}) : super(key: key);
@override
_SiteFormState createState() => state;
bool isValid() => state.validate();
}
class _SiteFormState extends State<SiteForm> {
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
}
final form = new GlobalKey<FormState>();
bool status=false;
List<bool>statuses=new List<bool>();
static List<String> _dropdownItems = ["Adventures and
Games","Beaches","Mountains","Hikes","Waterfalls and Lakes","Road Trips","Camps"];
String _dropdownValue= _dropdownItems[0];
List<Category>categories=[new Category(false,null),new Category(false,null),new
Category(false,null),new Category(false,null)];
String _errorText='';
TextEditingController _text = new TextEditingController();
bool _validate = false;
var regex=new RegExp("([A-Za-z]+[0-9]|[0-9]+[A-Za-z])[A-Za-z0-9]*");
@override
Widget build(BuildContext context) {
for(int i=0;i<4;i++){
statuses.add(false);
}
widget.site.categoryName=_dropdownValue;
return Container(
padding: EdgeInsets.all(16),
child: Material(
elevation: 1,
clipBehavior: Clip.antiAlias,
borderRadius: BorderRadius.circular(8),
child: Form(
key: form,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AppBar(
leading: Icon(Icons.location_on),
elevation: 0,
title: Text('Xsite'),
backgroundColor: Colors.blueGrey,
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: widget.onDelete,
)
],
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, top: 16),
child: TextFormField(
onChanged: (String value) {
setState(() {
if(value.length==0){
categories[0].filled=false;
categories[0].error="This field is required";
widget.site.name = "";
}
else{
categories[0].filled=true;
categories[0].error=null;
widget.site.name = value;
}
});
},
decoration: InputDecoration(
errorText: categories[0].error,
labelText: 'Site Name*',
hintText: "Enter the name of a specific place",
// errorText: statuses[0] ? 'Value Can\'t Be Empty' : null,
icon: Icon(Icons.add_location),
isDense: true,
),
),
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 9),
child: TextFormField(
onChanged: (String value) {
setState(() {
if(isAlpha(value)) {
categories[1].filled=true;
categories[1].error=null;
widget.site.country = value;
}
else if(value.length==0){
categories[1].filled=false;
categories[1].error="This field is required";
widget.site.country = "";
}
else{
categories[1].filled=false;
categories[1].error="Only contain alphabets";
widget.site.country = "";
}
});
},
decoration: InputDecoration(
labelText: 'Country*',
hintText: 'Enter the country of the site',
icon: Icon(Icons.my_location),
isDense: true,
errorText: categories[1].error,
),
),
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 9),
child: TextFormField(
decoration: InputDecoration(
labelText: 'City*',
hintText: 'Enter the City of the site',
icon: Icon(Icons.location_city),
isDense: true,
errorText: categories[2].error,
//errorText: statuses[1] ? 'Value Can\'t Be Empty' : null,
),
onChanged: (String value) {
setState(() {
if(isAlpha(value)) {
categories[2].filled=true;
categories[2].error=null;
widget.site.city = value;
}
else if(value.length==0){
categories[2].filled=false;
categories[2].error="This field is required";
widget.site.city = "";
}
else{
categories[2].filled=false;
categories[2].error="Only contain alphabets";
widget.site.city = "";
}
});
},
),
),
Padding(
padding: EdgeInsets.only(left: 16, right: 16, bottom: 16),
child: TextFormField(
validator: (val) =>
inrange(widget.site.mapAddress) ? null : 'Address is invalid',
decoration: InputDecoration(
labelText: 'Google maps address',
hintText: 'E.g: 24.658154, 26.225756',
icon: Icon(Icons.map),
isDense: true,
errorText: categories[3].error,
),
onChanged: (String value){
setState(() {
if(!inrange(value)) {
categories[3].filled = false;
categories[3].error = 'Wrong format of map address';
widget.site.mapAddress = "";
}
else{
categories[3].filled=true;
categories[3].error=null;
widget.site.mapAddress = value;
}
});
},
),
),
Padding(
padding: EdgeInsets.only(left: 15.0, right: 0, bottom: 11),
child:Row(children: <Widget>[
Icon(Icons.category,color: Colors.grey,),
Text(' Category of Site',style: TextStyle(color: Colors.blue,fontSize: 15.0),)
]
)
),
],
),
),
),
);
}
///form validator
bool validate() {
bool val=true;
if(widget.site.city=="" || !isAlpha(widget.site.city)){
setState(() {
categories[2].error="This field is required";
val=false;
});
}
if(widget.site.country=="" || !isAlpha(widget.site.country)){
setState(() {
categories[1].error="This field is required";
val=false;
});
}
if(widget.site.name=="" || !isAlpha(widget.site.name)){
setState(() {
categories[0].error="This field is required";
val=false;
});
}
for(int i=0;i<categories.length;i++){
if(!categories[i].filled){
val=false;
}
}
if(!val){
return false;
}
print(val);
print("formaaaaaaaatology");
return true;
}
bool inrange(String maps){
int count=0;
if(maps.length==0){
return true;
}
for (int i=0;i<maps.length;i++){
if(maps[i]==','){
count++;
}
}
if(count==0 || count>1){
return false;
}
double min=double.parse(maps.substring(0,maps.indexOf(',')));
double max=double.parse(maps.substring(maps.indexOf(',')+1,maps.length));
if(!(min>=-90 && min<=90)){
return false;
}
else if(!(max>=-180 && max<=80)){
return false;
}
else {
return true;
};
}
validateCountry(val){
if(val.length>0 ) {
print("koukeyeee");
setState(() {
this.widget.site.country="kousaay";
});
return null;
}
return 'This field is required';
}
}
这是在其他页面调用表单验证的代码:
bool onSave() {
if (sites.length > 0) {
var allValid = true;
sites.forEach((form) => allValid=form.validate() );
if (allValid) {
var data = sites.map((it) => it.site).toList();
Navigator.push(context,MaterialPageRoute(builder: (context) => ConnectorBiography()),);
return true;
}
else{
print("noot valid");
return false;
}
else{
Text("failed");
}
}
我通过将 class 编辑为 :
解决了我的问题class SiteForm extends StatefulWidget {
final ManageSiteModel site;
final OnDelete onDelete;
//adding new to this will remove the forms.
var state= _SiteFormState();
SiteForm({Key key, this.site, this.onDelete}) : super(key: key);
@override
_SiteFormState createState(){
return this.state=new _SiteFormState();
}
bool isValid() => this.state.validate();
}