Передача даних у StatefulWidget та доступ до них у своєму стані у Flutter


124

У моєму додатку Flutter у мене є 2 екрани: список записів та екран для створення та редагування записів.

Якщо я передаю об'єкт на другий екран, це означає, що я збираюсь відредагувати це, і якщо я перенесу нульове значення, це означає, що я створюю новий елемент. Екран редагування - віджет Stateful, і я не впевнений, як використовувати такий підхід https://flutter.io/cookbook/navigation/passing-data/ для мого випадку.

class RecordPage extends StatefulWidget {
  final Record recordObject;

  RecordPage({Key key, @required this.recordObject}) : super(key: key);

  @override
  _RecordPageState createState() => new _RecordPageState();
}

class _RecordPageState extends State<RecordPage> {
  @override
  Widget build(BuildContext context) {
   //.....
  }
}

Як я можу отримати доступ до recordObject всередині _RecordPageState ?



як ми можемо використовувати значення змінної 'recordObject' у функції класу _RecordPageState?
Камлеш

Відповіді:


208

Щоб використовувати recordObject в _RecordPageState, вам потрібно просто написати widget.objectname, як показано нижче

class _RecordPageState extends State<RecordPage> {
  @override
  Widget build(BuildContext context) {
   .....
   widget.recordObject
   .....
  }
}

9
Тим, хто не знайомий з Flutter, не забудьте визначити віджет на зразок "@override RecordPage get widget => super.widget;"
hhk

22
@hhk Чому це потрібно?
Herohtar

2
Чи не recordObjectслід бути частиною Stateкласу? За логікою, це StatefulWidgetнеправильно (з точки зору згуртованості). Окрім того, усі поля системи StatefulWidgetмають бути незмінними - що робити, якщо ви хочете змінити recordObjectпосилання?
Олексій Семенюк

У мене точно так само, і це не працює, роблячи щось на кшталт Text(widget.recordObject), воно говорить про те, що мій вар є нульовим
Дані

як ми можемо використовувати значення змінної 'recordObject' у функції класу _RecordPageState?
Камлеш

32
class RecordPage extends StatefulWidget {
  final Record recordObject;

  RecordPage({Key key, @required this.recordObject}) : super(key: key);

  @override
  _RecordPageState createState() => new _RecordPageState(recordObject);
}

class _RecordPageState extends State<RecordPage> {
  Record  recordObject
 _RecordPageState(this. recordObject);  //constructor
  @override
  Widget build(BuildContext context) {.    //closure has access
   //.....
  }
}

1
Поясніть, будь ласка, чому це державний віджет.
localhoost

@atilkan, оскільки початковий сценарій OP - це StatefulWidget, він просто додав рядки для відповідності потребам.
adadion

3
Я не думаю, що мати recordObjectполе і в, Stateі на StatefulWidgetзаняттях - це не дуже гарна ідея (хоча я бачив, що уроки роблять саме це). Підхід доступу до полів StatefulWidgetза допомогою widgetполя Stateкласу здається більш правильним підходом (навіть якщо у нього є свої проблеми)
Олексій Семенюк,

21

Повний приклад

Вам не потрібно передавати параметри State за допомогою конструктора. Ви можете легко отримати доступ до них за допомогою widget.myField .

class MyRecord extends StatefulWidget {
  final String recordName;
  const MyRecord(this.recordName);

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

class MyRecordState extends State<MyRecord> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.recordName); // Here you direct access using widget
  }
}

Передайте свої дані під час навігації по екрану:

 Navigator.of(context).push(MaterialPageRoute(builder: (context) => MyRecord("WonderWorld")));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.