“带有不匹配参数的闭幕电话”,但我不知道为什么

时间:2019-11-23 11:45:22

标签: flutter dart

当我尝试在Flutter应用程序中提交表单时,出现“带有不匹配参数的结束调用”错误,并且我不知道它为什么发生。我的handleInputSave函数似乎有问题,但是我只调用了一次,并且已经多次确认参数正确。

完整错误:

I/flutter ( 6655): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter ( 6655): The following NoSuchMethodError was thrown while handling a gesture:
I/flutter ( 6655): Closure call with mismatched arguments: function '_MetricState.build.<anonymous closure>'
I/flutter ( 6655): Receiver: Closure: (dynamic) => bool
I/flutter ( 6655): Tried calling: _MetricState.build.<anonymous closure>()
I/flutter ( 6655): Found: _MetricState.build.<anonymous closure>(dynamic) => bool
I/flutter ( 6655):
I/flutter ( 6655): When the exception was thrown, this was the stack:
I/flutter ( 6655): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter ( 6655): #1      NumberInputState.build.<anonymous closure> (package:greeklibrary/components/Select/Metric/numberinput.dart:60:26)
I/flutter ( 6655): #2      FormFieldState._validate (package:flutter/src/widgets/form.dart)
I/flutter ( 6655): #3      FormFieldState.validate.<anonymous closure> (package:flutter/src/widgets/form.dart:364:7)
I/flutter ( 6655): #4      State.setState (package:flutter/src/widgets/framework.dart:1141:30)
I/flutter ( 6655): #5      FormFieldState.validate (package:flutter/src/widgets/form.dart:363:5)
I/flutter ( 6655): #6      FormState._validate (package:flutter/src/widgets/form.dart:203:25)
I/flutter ( 6655): #7      FormState.validate (package:flutter/src/widgets/form.dart:197:12)
I/flutter ( 6655): #8      _MetricState.build.<anonymous closure> (package:greeklibrary/components/Select/Metric/metric.dart:48:51)
I/flutter ( 6655): #9      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:654:14)
I/flutter ( 6655): #10     _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:729:32)
I/flutter ( 6655): #11     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
I/flutter ( 6655): #12     TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:365:11)
I/flutter ( 6655): #13     TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:275:7)
I/flutter ( 6655): #14     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:455:9)
I/flutter ( 6655): #15     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:75:13)
I/flutter ( 6655): #16     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:102:11)
I/flutter ( 6655): #17     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
I/flutter ( 6655): #18     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
I/flutter ( 6655): #19     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
I/flutter ( 6655): #20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
I/flutter ( 6655): #21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
I/flutter ( 6655): #25     _invoke1 (dart:ui/hooks.dart:263:10)
I/flutter ( 6655): #26     _dispatchPointerDataPacket (dart:ui/hooks.dart:172:5)
I/flutter ( 6655): (elided 3 frames from package dart:async)
I/flutter ( 6655):
I/flutter ( 6655): Handler: "onTap"
I/flutter ( 6655): Recognizer:
I/flutter ( 6655):   TapGestureRecognizer#8abdf
I/flutter ( 6655): ════════════════════════════════════════════════════════════════════════════════════════════════════

“指标(父级)”小部件:

import "package:flutter/material.dart";
import 'package:greeklibrary/styles/variables.dart';

import "./numberinput.dart";

class Metric extends StatefulWidget {
  @override
  _MetricState createState() => _MetricState();
}

class _MetricState extends State<Metric> {
  final _formKey = GlobalKey<FormState>();

  var _formData = {};

  void handleInputSave(String name, String value) {
    print("called");
    setState(() => _formData[name] = value);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: colorPrimary,
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 25.0),
        child: Center(
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                NumberInput(
                  name: "book",
                  defaultValue: "1",
                  validator: (value) =>
                      !RegExp(r"^[0-9]$").hasMatch(value) &&
                      !RegExp(r"^[1-2][0-4]$").hasMatch(value),
                  onSaved: (String name, String value) =>
                      handleInputSave(name, value),
                ),
                SizedBox(
                  height: 20.0,
                ),
                RaisedButton(
                    child: Text("Ἀγε!"),
                    onPressed: () {
                      print(_formKey.currentState.validate());
                      if (_formKey.currentState.validate()) {
                        // _formKey.currentState.save();
                        print("succeeded");
                        //  Navigator.of(context).pushNamed("/loading");
                      }
                    })
              ],
            ),
          ),
        ),
      ),
    );
  }
}

NumberInput(子级)小部件:

import "package:flutter/material.dart";

class NumberInput extends StatefulWidget {
  final String name;
  final String defaultValue;
  final Function validator;
  final Function onSaved;

  NumberInput({this.name, this.defaultValue, this.validator, this.onSaved});

  @override
  NumberInputState createState() => NumberInputState();
}

class NumberInputState extends State<NumberInput> {
  String value;

  @override
  void initState() {
    super.initState();
    setState(() => value = widget.defaultValue);
    print(widget.onSaved);
  }

  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        ButtonTheme(
          minWidth: 14.0,
          buttonColor: Color.fromRGBO(0, 0, 0, 0.0),
          child: RaisedButton(
            child: Text(
              "-",
              style: TextStyle(fontSize: 32.0),
            ),
            elevation: 1,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(18.0),
            ),
            onPressed: () {
              setState(() {
                if (int.parse(value) > 1) {
                  value = (int.parse(value) - 1).toString();
                }
              });
            },
          ),
        ),
        SizedBox(
          width: 16.0,
        ),
        Flexible(
          child: TextFormField(
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              labelText: "Vul een boeknummer in",
            ),
            controller: TextEditingController(text: value),
            validator: (value) {
              if (widget.validator()) {
                return "Vul alstublieft een (geldig) booknummer in.";
              }
              return null;
            },
            onSaved: (value) {
              widget.onSaved(widget.name, value);
            },
          ),
        ),
        SizedBox(
          width: 16.0,
        ),
        ButtonTheme(
          minWidth: 14.0,
          buttonColor: Color.fromRGBO(0, 0, 0, 0.0),
          child: RaisedButton(
            child: Text(
              "+",
              style: TextStyle(fontSize: 32.0),
            ),
            elevation: 1,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(18.0),
            ),
            onPressed: () {
              setState(() => value = (int.parse(value) + 1).toString());
            },
          ),
        ),
      ],
    );
  }
}

1 个答案:

答案 0 :(得分:0)

您忘记将值作为验证器的参数
您可以在
下面复制粘贴运行完整代码 代码段

if (widget.validator(value)) {
            return "Vul alstublieft een (geldig) booknummer in.";
          }

演示

enter image description here

完整代码

    import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(flex:1, child: Metric()),
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class Metric extends StatefulWidget {
  @override
  _MetricState createState() => _MetricState();
}

class _MetricState extends State<Metric> {
  final _formKey = GlobalKey<FormState>();

  var _formData = {};

  void handleInputSave(String name, String value) {
    print("called");
    setState(() => _formData[name] = value);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,//colorPrimary,
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 25.0),
        child: Center(
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                NumberInput(
                  name: "book",
                  defaultValue: "1",
                  validator: (value) =>
                  !RegExp(r"^[0-9]$").hasMatch(value) &&
                      !RegExp(r"^[1-2][0-4]$").hasMatch(value),
                  onSaved: (String name, String value) =>
                      handleInputSave(name, value),
                ),
                SizedBox(
                  height: 20.0,
                ),
                RaisedButton(
                    child: Text("Ἀγε!"),
                    onPressed: () {
                      print(_formKey.currentState.validate());
                      if (_formKey.currentState.validate()) {
                        // _formKey.currentState.save();
                        print("succeeded");
                        //  Navigator.of(context).pushNamed("/loading");
                      }
                    })
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class NumberInput extends StatefulWidget {
  final String name;
  final String defaultValue;
  final Function validator;
  final Function onSaved;

  NumberInput({this.name, this.defaultValue, this.validator, this.onSaved});

  @override
  NumberInputState createState() => NumberInputState();
}

class NumberInputState extends State<NumberInput> {
  String value;

  @override
  void initState() {
    super.initState();
    setState(() => value = widget.defaultValue);
    print(widget.onSaved);
  }

  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        ButtonTheme(
          minWidth: 14.0,
          buttonColor: Color.fromRGBO(0, 0, 0, 0.0),
          child: RaisedButton(
            child: Text(
              "-",
              style: TextStyle(fontSize: 32.0),
            ),
            elevation: 1,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(18.0),
            ),
            onPressed: () {
              setState(() {
                if (int.parse(value) > 1) {
                  value = (int.parse(value) - 1).toString();
                }
              });
            },
          ),
        ),
        SizedBox(
          width: 16.0,
        ),
        Flexible(
          child: TextFormField(
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              labelText: "Vul een boeknummer in",
            ),
            controller: TextEditingController(text: value),
            validator: (value) {
              if (widget.validator(value)) {
                return "Vul alstublieft een (geldig) booknummer in.";
              }
              return null;
            },
            onSaved: (value) {
              widget.onSaved(widget.name, value);
            },
          ),
        ),
        SizedBox(
          width: 16.0,
        ),
        ButtonTheme(
          minWidth: 14.0,
          buttonColor: Color.fromRGBO(0, 0, 0, 0.0),
          child: RaisedButton(
            child: Text(
              "+",
              style: TextStyle(fontSize: 32.0),
            ),
            elevation: 1,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(18.0),
            ),
            onPressed: () {
              setState(() => value = (int.parse(value) + 1).toString());
            },
          ),
        ),
      ],
    );
  }
}