我用于产品创建和更新(重用)的此文件。当我创建产品时,效果很好。但是,当我单击更新时,以前的产品就会显示错误。
I/flutter ( 8544): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter ( 8544): The following NoSuchMethodError was thrown while handling a gesture:
I/flutter ( 8544): The method 'call' was called on null.
I/flutter ( 8544): Receiver: null
I/flutter ( 8544): Tried calling: call(_LinkedHashMap len:4)
I/flutter ( 8544):
I/flutter ( 8544): When the exception was thrown, this was the stack:
这是我的完整代码:
import 'package:flutter/material.dart';
import '../widgets/helpers/ensure_visible.dart';
class product_Edit extends StatefulWidget {
Function addProduct;
Function updateProduct;
Map<String, dynamic> product;
int productIndex;
product_Edit(
{this.addProduct, this.productIndex, this.product, this.updateProduct});
@override
State<StatefulWidget> createState() {
return _product_EditState();
}
}
class _product_EditState extends State<product_Edit> {
final Map<String, dynamic> _formData = {
'imageUrl': 'assets/food.jpg',
'title': Null,
'description': Null,
'price': Null
};
final _titleFocusNode = FocusNode();
final _descriptionFocusNode = FocusNode();
final _priceFocusNode = FocusNode();
final GlobalKey<FormState> _globalFormKey = GlobalKey<FormState>();
Widget _productNameTextField() {
return EnsureVisibleWhenFocused(
focusNode: _titleFocusNode,
child: TextFormField(
focusNode: _titleFocusNode,
decoration: InputDecoration(labelText: 'Product Name'),
initialValue: widget.product == null ? '' : widget.product['title'],
validator: (String value) {
if (value.isEmpty || value.length < 5) {
return "Title is required and Should be 5+ characters long!";
}
},
onSaved: (String value) {
setState(() {
_formData['title'] = value;
});
},
),
);
}
Widget _productDescriptionTextField() {
return EnsureVisibleWhenFocused(
focusNode: _descriptionFocusNode,
child: TextFormField(
focusNode: _descriptionFocusNode,
decoration: InputDecoration(labelText: 'Product Description'),
maxLines: 4,
initialValue:
widget.product == null ? '' : widget.product['description'],
validator: (String value) {
if (value.trim().length < 8) {
return "Description is required and Should be 8+ characters long!";
}
},
onSaved: (String value) {
_formData['description'] = value;
},
),
);
}
Widget _productPriceTextField() {
return EnsureVisibleWhenFocused(
focusNode: _priceFocusNode,
child: TextFormField(
focusNode: _priceFocusNode,
decoration: InputDecoration(labelText: 'Product Price'),
initialValue:
widget.product == null ? '' : widget.product['price'].toString(),
validator: (String value) {
if (value.isEmpty ||
!RegExp(r'^(?:[1-9]\d*|0)?(?:\.\d+)?$').hasMatch(value)) {
return "Price is required and should be number!";
}
},
onSaved: (String value) {
_formData['price'] = double.parse(value);
},
keyboardType: TextInputType.number,
),
);
}
void _submitForm() {
if (!_globalFormKey.currentState.validate()) {
return;
}
_globalFormKey.currentState.save();
if (widget.product == null) {
widget.addProduct(_formData);
} else if (widget.product != null) {
//widget.updateProduct(widget.productIndex,_formData);
widget.addProduct(_formData);
}
Navigator.pushReplacementNamed(context, '/products');
}
Widget _buildPageContent() {
final double deviceWidth = MediaQuery.of(context).size.width;
final double targetWidth = deviceWidth > 500 ? 500 : deviceWidth * 0.95;
final double targetPadding = deviceWidth - targetWidth;
return Container(
padding: EdgeInsets.all(10.0),
child: Form(
key: _globalFormKey,
child: ListView(
padding: EdgeInsets.symmetric(horizontal: targetPadding / 2),
children: <Widget>[
_productNameTextField(),
_productDescriptionTextField(),
_productPriceTextField(),
SizedBox(
height: 6.0,
),
RaisedButton(
color: Theme.of(context).accentColor,
child: Text(
'Save',
style: TextStyle(color: Colors.white),
),
onPressed: _submitForm)
],
),
),
);
}
@override
Widget build(BuildContext context) {
Widget pageContent = _buildPageContent();
return widget.product == null
? pageContent
: Scaffold(
appBar: AppBar(
title: Text('Edit Text'),
),
body: pageContent,
);
}
}