在 null 上调用了方法 'map'。 & 尝试调用:map<Answer>(Closure: (String) => Answer)

The method 'map' was called on null. & Tried calling: map<Answer>(Closure: (String) => Answer)

错误:

The following NoSuchMethodError was thrown building MyApp(dirty, state: _MyAppState#ad714):

  The method 'map' was called on null.
  Receiver: null
  Tried calling: map<Answer>(Closure: (String) => Answer)

我的代码:

import 'package:flutter/material.dart';


import './qestion.dart';
import 'answer.dart';

void main() {
  runApp(MyApp());
}



class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  var _questionIndex = 0;

  void _answerQuestion() {
    setState(() {
      _questionIndex = _questionIndex + 1;
    });
    print(_questionIndex);
    //print('Answer choosen');
  }

  Widget build(BuildContext context) {
    var questions = [
      {
        'questionText': 'what\'s your favorite color?',
        'answers': ['red', 'black', 'brown'],
      },
      {
        'questionText': 'what\s your favorite animal ?',
        'answers': ['lion', 'horse'],
      },
    ];

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('My First Application'),
        ),
        body: Column(
          children: [
            Question(
              questions[_questionIndex]['questionText'],
            ),

            ...(questions[_questionIndex]['answer'] as List<String>)
                    . map((answer) {
                  return Answer(_answerQuestion, answer);
                }).toList() 
                [],
            // RaisedButton(
            //   child: Text('Answer 2'),
            //   onPressed: () => {print('it is a =anonymus ans')},
            // ),
          ],
        ),
      ),
    );
  }
}

有问题的部分可能是:

        ...(questions[_questionIndex]['answer'] as List<String>)
                . map((answer) {
              return Answer(_answerQuestion, answer);
            }).toList() 

Question.dart:

import 'package:flutter/material.dart';

class Question extends StatelessWidget {
  // const Question({ Key? key }) : super(key: key);
  final String questionText;
  Question(this.questionText);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.all(10),
      width: double.infinity,
      child: Text(
        questionText,
        style: TextStyle(fontSize: 25),
        textAlign: TextAlign.center,
      ),
    );
  }
}

Answer.dart

import 'package:flutter/material.dart';

class Answer extends StatelessWidget {
  //const Answer({ Key? key }) : super(key: key);
  final Function selectHandler;
  final String answerText;
  Answer(this.selectHandler, this.answerText);

  @override
  Widget build(BuildContext context) {
    return Container(
        width: double.infinity,
        child: RaisedButton(
          textColor: Colors.black,
          color: Colors.cyan,
          child: Text(answerText),
          onPressed: selectHandler,
        ));
  }
}

如何解决 VScode 编辑器中的这个错误?

你打错了。在您声明变量的地方有 answers 字段,但您正在访问 answer 字段。

换下一行再看。

...(questions[_questionIndex]['answers'] as List<String>)
                    . map((answer) {
                  return Answer(_answerQuestion, answer);
                }).toList()

我们来谈谈主要部分,生成Answer个小部件。

questions[_questionIndex]['answers'] 为我们提供了每个问题的答案。通过映射,我们可以生成 List<Answer> 个小部件。这将是一个很长的表达式来处理(对我来说失败了),因此我使用 来生成 Answer 个小部件。

...() {
  final List<String?>? answers =
      questions[_questionIndex]['answers'] as List<String?>?;

  return answers == null
      ? [
          Text("could not find any answer"),
        ]
      : answers
          .map(
            (e) => Answer(
              selectHandler: _answerQuestion,
              answerText: e ?? "failed to get answer",
            ),
          )
          .toList();
}()

另一个常见问题是

Fuction can't be assing....void Function....

我们可以简单地使用VoidCallback代替Function,否则我们需要使用匿名函数来处理这个。

小问题,例如添加 @override、将数据移动到小部件级别、固定在完整代码段上的关键构造函数,我更喜欢并建议使用命名构造函数。您可以搜索并了解有关这些关键字的更多信息。

记得处理范围错误和页面导航,我在列表末尾停止 _questionIndex 增量。

运行 在 dartPad

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

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

class _MyAppState extends State<MyApp> {
  var _questionIndex = 0;
  var questions = [
    {
      'questionText': 'what\'s your favorite color?',
      'answers': ['red', 'black', 'brown'],
    },
    {
      'questionText': 'what\s your favorite animal ?',
      'answers': ['lion', 'horse'],
    },
    {
      'questionText': 'what\s your favorite animal ?',
    },
  ];
  void _answerQuestion() {
    setState(() {
      /// handle range error,
      if (_questionIndex < questions.length - 1) {
        _questionIndex += 1;
      }
    });
    print(_questionIndex);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('My First Application'),
        ),
        body: Column(
          children: [
            Question(
              questionText: questions[_questionIndex]['questionText'] as String,
            ),
            ...() {
              final List<String?>? answers =
                  questions[_questionIndex]['answers'] as List<String?>?;

              return answers == null
                  ? [
                      Text("could not find any answer"),
                    ]
                  : answers
                      .map(
                        (e) => Answer(
                          selectHandler: _answerQuestion,
                          answerText: e ?? "failed to get answer",
                        ),
                      )
                      .toList();
            }()
          ],
        ),
      ),
    );
  }
}

class Question extends StatelessWidget {
  // const Question({ Key? key }) : super(key: key);
  final String questionText;
  const Question({
    Key? key,
    required this.questionText,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.all(10),
      width: double.infinity,
      child: Text(
        questionText,
        style: const TextStyle(fontSize: 25),
        textAlign: TextAlign.center,
      ),
    );
  }
}

class Answer extends StatelessWidget {
  final VoidCallback selectHandler;
  final String answerText;

  const Answer({
    Key? key,
    required this.selectHandler,
    required this.answerText,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
        width: double.infinity,
        child: ElevatedButton(
          child: Text(answerText),
          onPressed: selectHandler,
        ));
  }
}