方法'call'在null上被调用。接收者:null

时间:2019-09-27 01:59:22

标签: flutter

我刚刚开始处理flutter应用程序,并且在按保存按钮时遇到这种异常。

在null上调用了方法“ call”。 接收者:null 尝试致电:致电(“产品”的实例)

据我所知,我认为我的工作还不错,但仍然无法找出该错误/异常。

我还附上了参考代码。

这是我的主文件

    class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ScopedModel<ProductsModel>(
      model: ProductsModel(),
      child: MaterialApp(
        theme: ThemeData(
          brightness: Brightness.light,
          primarySwatch: Colors.deepOrange,
          accentColor: Colors.deepPurple,
          buttonColor: Colors.deepPurple,
        ),
//      home: AuthPage(),
//      Either '/' or home stands for starting point of the app
        routes: {
          '/': (BuildContext context) => AuthPage(),
          '/product': (BuildContext context) => ProductsPage(),
          '/admin': (BuildContext context) => ProductsAdminPage()
        },
        onGenerateRoute: (RouteSettings settings) {
          final List<String> pathElements = settings.name.split('/');

          if (pathElements[0] != '') return null;

          if (pathElements[1] == 'product') {
            final int index = int.parse(pathElements[2]);
            return MaterialPageRoute<bool>(
              builder: (BuildContext context) =>
                  ProductPage(null, null, null, null),
            );
          }

          return null;
        },
        onUnknownRoute: (RouteSettings settings) {
          return MaterialPageRoute(
            builder: (BuildContext context) => ProductsPage(),
          );
        },
      ),
    );
  }

然后从这里导航到添加/编辑页面。

class ProductEditPage extends StatefulWidget {
  final Function addProduct;
  final Function updateProduct;
  final Product product;
  final int productIndex;

  ProductEditPage(
      {this.addProduct, this.updateProduct, this.product, this.productIndex});

  @override
  State<StatefulWidget> createState() {
    return _ProductEditPageState();
  }
}

class _ProductEditPageState extends State<ProductEditPage> {
  final Map<String, dynamic> _formData = {
    'title': null,
    'description': null,
    'price': null,
    'image': 'assets/food.jpg'
  };
  final GlobalKey<FormState> _globalKey = GlobalKey<FormState>();
  final _titleFocusNode = FocusNode();
  final _descriptionFocusNode = FocusNode();
  final _priceFocusNode = FocusNode();

  Widget _buildTitleTextField() {
    return EnsureVisibleWhenFocused(
        child: TextFormField(
          focusNode: _titleFocusNode,
          decoration: InputDecoration(labelText: 'Product Title'),
          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";
            else
              return null;
          },
          onSaved: (String value) {
            _formData['title'] = value;
          },
        ),
        focusNode: _titleFocusNode);
  }

  Widget _buildDescriptionTextField() {
    return EnsureVisibleWhenFocused(
        child: TextFormField(
          decoration: InputDecoration(labelText: 'Product Description'),
          maxLines: 10,
          focusNode: _descriptionFocusNode,
          initialValue:
              widget.product != null ? widget.product.description : "",
          validator: (String value) {
            if (value.isEmpty || value.length < 10)
              return "Description is required and should be 10+ characters long";
            else
              return null;
          },
          onSaved: (String value) {
            _formData['description'] = value;
          },
        ),
        focusNode: _descriptionFocusNode);
  }

  Widget _buildPriceTextField() {
    return EnsureVisibleWhenFocused(
        child: TextFormField(
          decoration: InputDecoration(labelText: 'Product Price'),
          keyboardType:
              TextInputType.numberWithOptions(decimal: true, signed: true),
          focusNode: _priceFocusNode,
          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 a number";
            else
              return null;
          },
          onSaved: (String value) {
            _formData['price'] = double.parse(value);
          },
        ),
        focusNode: _priceFocusNode);
  }

  Widget _buildSubmitButton() {
    return ScopedModelDescendant<ProductsModel>(
      builder: (BuildContext context, Widget child, ProductsModel model) {
        return RaisedButton(
          child: Text('SAVE'),
          textColor: Colors.white,
          onPressed: () =>
              _onSavePressed(model.addProduct, model.updateProduct),
        );
      },
    );
  }

  Widget _buildPageContent(BuildContext context) {
    final double deviceWidth = MediaQuery.of(context).size.width;
    final double targetWidth =
        MediaQuery.of(context).orientation == Orientation.portrait
            ? deviceWidth * 0.95
            : deviceWidth * 0.75;
    final double targetPadding = deviceWidth - targetWidth;

    return GestureDetector(
      onTap: () {
        FocusScope.of(context).requestFocus(FocusNode());
      },
      child: Container(
        margin: EdgeInsets.all(10.0),
        child: Form(
          key: _globalKey,
          child: ListView(
            padding: EdgeInsets.symmetric(horizontal: targetPadding / 2),
            children: <Widget>[
              _buildTitleTextField(),
              _buildDescriptionTextField(),
              _buildPriceTextField(),
              SizedBox(
                height: 10.0,
              ),
              _buildSubmitButton(),
//          GestureDetector(
//            onTap: _onSavePressed,
//            child: Container(
//              color: Colors.green,
//              padding: EdgeInsets.all(5.0),
//              child: Text('SAVE'),
//            ),
//          )
            ],
          ),
        ),
      ),
    );
  }

  void _onSavePressed(Function addProduct, Function updateProduct) {
    if (!_globalKey.currentState.validate()) {
      return;
    }
    _globalKey.currentState.save();
    if (widget.product == null) {
      widget.addProduct(
        Product(
            title: _formData['title'],
            image: _formData['image'],
            price: _formData['price'],
            description: _formData['description']),
      );
    } else {
      widget.updateProduct(
          widget.productIndex,
          Product(
              title: _formData['title'],
              image: _formData['image'],
              price: _formData['price'],
              description: _formData['description']));
    }

    Navigator.pushNamed(context, '/product');
  }

  @override
  Widget build(BuildContext context) {
    final Widget pageContent = _buildPageContent(context);

    return widget.product == null
        ? pageContent
        : Scaffold(
            appBar: AppBar(
              title: Text('Edit Product'),
            ),
            body: pageContent,
          );
  }

这是产品型号类别

class Product {
  final String title;
  final String description;
  final double price;
  final String image;

  Product(
      {@required this.title,
      @required this.description,
      @required this.price,
      @required this.image});
}

这也是日志

════════ Exception caught by gesture ═══════════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown while handling a gesture:
The method 'call' was called on null.
Receiver: null
Tried calling: call(Instance of 'Product')

When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1      _ProductEditPageState._onSavePressed (package:flutter_app/pages/product_edit.dart:157:14)
#2      _ProductEditPageState._buildSubmitButton.<anonymous closure>.<anonymous closure> (package:flutter_app/pages/product_edit.dart:104:15)
#3      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:654:14)
#4      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:729:32)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#1e958
  debugOwner: GestureDetector
  state: ready
  won arena
  finalPosition: Offset(95.0, 358.0)
  finalLocalPosition: Offset(94.0, 23.0)
  sent tap down
════════════════════════════════════════════════════════════════════════════════════════════════════

任何帮助!!!!

1 个答案:

答案 0 :(得分:1)

该错误表示您正在尝试将null变量作为函数调用。

在您的_onSavePressed方法上,您正在调用widget.addProduct函数,该函数实际上为空。您应该调用作为参数传递的addProduct函数,如下所示:

void _onSavePressed(Function addProduct, Function updateProduct) {
    if (!_globalKey.currentState.validate()) {
      return;
    }
    _globalKey.currentState.save();
    if (widget.product == null) {
      addProduct(       // change here
        Product(
            title: _formData['title'],
            image: _formData['image'],
            price: _formData['price'],
            description: _formData['description']),
      );
    } else {
      updateProduct(    // change here
          widget.productIndex,
          Product(
              title: _formData['title'],
              image: _formData['image'],
              price: _formData['price'],
              description: _formData['description']));
    }

    Navigator.pushNamed(context, '/product');
  }