Передача данных в StatefulWidget и доступ к ним в его состоянии во Flutter

127

В моем приложении Flutter есть 2 экрана: список записей и экран для создания и редактирования записей.

Если я передаю объект на второй экран, это означает, что я собираюсь его отредактировать, а если я передаю значение null, это означает, что я создаю новый элемент. Экран редактирования - это виджет с отслеживанием состояния, и я не уверен, как использовать этот подход 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 ?

Moonvader
источник
1
Возможный дубликат передачи данных в виджет с
отслеживанием
как мы можем использовать значение переменной recordObject в функции класса _RecordPageState?
Камлеш

Ответы:

211

Чтобы использовать recordObject в _RecordPageState, вам нужно просто написать widget.objectname, как показано ниже

class _RecordPageState extends State<RecordPage> {
  @override
  Widget build(BuildContext context) {
   .....
   widget.recordObject
   .....
  }
}
dhuma1981
источник
9
Те, кто плохо знаком с Flutter, не забудьте определить виджет типа «@override RecordPage get widget => super.widget;»
hhk
22
@hhk Зачем это нужно?
Herohtar
2
Разве это не recordObjectдолжно быть частью Stateкласса? Логично, что это StatefulWidgetнеправильно (с точки зрения сплоченности). Кроме того, все поля StatefulWidgetдолжны быть неизменными - что, если вы захотите изменить recordObjectссылку?
Alex
У меня точно такое же, и он не работает, что-то вроде Text(widget.recordObject), он говорит, что мой var равен нулю
Дэни
как мы можем использовать значение переменной 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с использованием widgetfield of Stateclass кажется более правильным подходом (хотя у него есть свои проблемы)
Alex
23

Полный пример

Вам не нужно передавать параметры в 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")));
Санджайраджсинх
источник