使用另一个类的实例访问有状态窗口小部件的变量时,调用getter的长度为null

问题描述 投票:0回答:1

最初,我使用页面路由将数据发送到下一页(问题)。 (数据是列表类型)

Navigator.pushReplacement(context,MaterialPageRoute(
                                        builder: (context) => Question(
                                            questions: this.questions)));

然后,我使用构造函数在Question Stateful类中接收了值,并将其值设置为另一个变量。

问题类别:

class Question extends StatefulWidget {
  final List<QuestionModel> questions;

    const Question({this.questions});

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

class _QuestionState extends State<Question> {
  @override
  void initState() {
    super.initState();
    print(widget.questions); //<----------working
  }

  @override
  Widget build(BuildContext context){
  return Scaffold(
    body: Column(
      children: <Widget>[
        Timer(),
        SizedBox(height: 40),
        Expanded(child: QuestionBuilder())
      ],
    ),
  );}

当我尝试在“问题”状态下打印问题列表时,它非常正常。

但是我需要在另一个类QuestionBuilder中使用该值。因此,我使用问题类的实例访问该值。

 class QuestionBuilder extends StatefulWidget {
      @override
      _QuestionBuilderState createState() => _QuestionBuilderState();
    }

        class _QuestionBuilderState extends State<QuestionBuilder> {
          List<QuestionModel> questions;

          @override
          void initState() {
            super.initState();
            questions = Question().questions;
            print(questions); //<---------------not working
          } 

         @override
       Widget build(BuildContext context) {
    return PageView.builder(
      itemCount: questions.length ?? 0,
      itemBuilder: (context, index) {
        return SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    Text(
                      "Question  ${index + 1} / ",
                      style: Styles.questionNumberTextStyle,
                    ),
                    Text(
                      "7",
                      style:
                          Styles.questionNumberTextStyle.copyWith(fontSize: 20),
                    ),
                  ],
                ),
              ),
              SizedBox(height: 20),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Text(
                  questions[index].question,
                  style: Styles.questionTextStyle,
                  textAlign: TextAlign.left,
                ),
              ),
              SizedBox(height: 20),
              option(option: questions[index].option_1, onTap: () {}),
              option(option: questions[index].option_2, onTap: () {}),
              option(option: questions[index].option_3, onTap: () {}),
              option(option: questions[index].option_4, onTap: () {}),
              SizedBox(height: 20),
            ],
          ),
        );
      },
    );
  }}

现在,当我打印问题列表时,它为null,并且当我在PageView或ListView中使用它时,错误显示getter长度在null上被调用。

enter image description here

我不知道是什么原因引起的。此外,当尝试手动将虚拟列表值分配给Question类中的问题列表时。它可以在QuestionBuilder类中使用]

flutter flutter-layout flutter-dependencies flutter-animation flutter-test
1个回答
1
投票

问题是您正在使用此代码创建Question类的新实例:

questions = Question().questions;

一种简单的方法是在params中传递值。例如,在问题类中,将数据传递给您在其中调用QuestionBuilder()的参数,如下所示:

 @override
  Widget build(BuildContext context){
  return Scaffold(
    body: Column(
      children: <Widget>[
        Timer(),
        SizedBox(height: 40),
        Expanded(child: QuestionBuilder(widget.questions),
)
      ],
    ),
  );}

现在定义一个变量来访问在参数中传递的该值,如下所示:

 class QuestionBuilder extends StatefulWidget {
final List<QuestionModel> questions;
QuestionBuilder(this.questions);
      @override
      _QuestionBuilderState createState() => _QuestionBuilderState();
    }

现在位于QuestionBuilder的initState中,可以按如下方式访问问题列表:

 @override
          void initState() {
            super.initState();
            questions = widget.questions;
            print(questions); //<---------------this will work now
          } 

所以现在您的更正代码将是,对于问题类:

class Question extends StatefulWidget {
  final List<QuestionModel> questions;

    const Question({this.questions});

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

class _QuestionState extends State<Question> {
  @override
  void initState() {
    super.initState();
    print(widget.questions); 
  }

  @override
  Widget build(BuildContext context){
  return Scaffold(
    body: Column(
      children: <Widget>[
        Timer(),
        SizedBox(height: 40),
        Expanded(child: QuestionBuilder(widget.questions))
      ],
    ),
  );}

和QuestionBuilder将是:

class QuestionBuilder extends StatefulWidget {
final List<QuestionModel> questions;
QuestionBuilder(this.questions);
      @override
      _QuestionBuilderState createState() => _QuestionBuilderState();
    }

        class _QuestionBuilderState extends State<QuestionBuilder> {
          List<QuestionModel> questions;

          @override
          void initState() {
            super.initState();
            questions = widget.questions;
            print(questions); //<---------------not working
          } 

         @override
       Widget build(BuildContext context) {
    return PageView.builder(
      itemCount: questions.length ?? 0,
      itemBuilder: (context, index) {
        return SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    Text(
                      "Question  ${index + 1} / ",
                      style: Styles.questionNumberTextStyle,
                    ),
                    Text(
                      "7",
                      style:
                          Styles.questionNumberTextStyle.copyWith(fontSize: 20),
                    ),
                  ],
                ),
              ),
              SizedBox(height: 20),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Text(
                  questions[index].question,
                  style: Styles.questionTextStyle,
                  textAlign: TextAlign.left,
                ),
              ),
              SizedBox(height: 20),
              option(option: questions[index].option_1, onTap: () {}),
              option(option: questions[index].option_2, onTap: () {}),
              option(option: questions[index].option_3, onTap: () {}),
              option(option: questions[index].option_4, onTap: () {}),
              SizedBox(height: 20),
            ],
          ),
        );
      },
    );
  }}
© www.soinside.com 2019 - 2024. All rights reserved.