длина получателя, равная нулю, при доступе к переменной виджета с состоянием с использованием его экземпляра из другого класса - PullRequest
0 голосов
/ 26 апреля 2020

Изначально я использовал маршрут страницы для отправки данных на следующую страницу (Вопрос). (Данные являются типом списка)

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),
            ],
          ),
        );
      },
    );
  }}

Теперь, когда я печатаю Список вопросов, он является нулевым, и, далее, когда я использовал его в PageView или ListView, ошибка показывает, что длина получателя была названа нулевой.

enter image description here

Я не знаю, в чем причина проблемы. Более того, при попытке вручную назначить фиктивное значение списка вопросов в классе вопросов. Работает в классе QuestionBuilder

1 Ответ

3 голосов
/ 26 апреля 2020

Проблема в том, что вы создаете новый экземпляр класса Question с помощью этого кода:

questions = Question().questions;

Один из простых способов - передать значение в параметрах. Например, в классе вопроса передайте данные в параметр, где вы вызываете 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();
    }

Теперь в initState of QuestionBuilder доступ к QuestionList выглядит следующим образом:

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

Так что теперь ваш исправленный код будет таким: Для класса Question:

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),
            ],
          ),
        );
      },
    );
  }}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...