Лучший способ передачи данных между виджетами во Flutter

Я разрабатываю свой собственный виджет, который используется в другом представлении. В этом пользовательском виджете у меня есть одно свойство класса, которое хранит информацию, скажем, что это список, который получает новые элементы внутри виджета. Теперь я хочу получить элементы из этого списка с уровня моего основного виджета.

Как это сделать? Я не хочу создавать переменную, как это: var customWidget = MyCustomWidget() а затем получить внутреннюю переменную, как customWidget.createState().myList - Я думаю, что это ужасное решение (и я не уверен, что оно будет работать). Также передача списка конструктору моего пользовательского виджета выглядит очень некрасиво.

Есть ли другой способ получить состояние другого виджета?

2 ответа

Во-первых, помните, что в Flutter данные могут передаваться только вниз. Из-за этого не возможно получить доступ к данным детей, только родителей (хотя есть некоторые взломы вокруг этого).

С этого момента, есть 2 основных решения для передачи данных:

  1. Добавьте нужные данные в ваши конструкторы виджетов.

Я не думаю, что здесь есть что сказать. Легко использовать. Но скучно, когда вы хотите передать одно поле всему вашему дереву виджетов. Используйте этот метод только тогда, когда область действия значения ограничена. Если это что-то вроде конфигурации или пользовательских данных, перейдите ко второму решению.

class Bar extends StatelessWidget {
  final String data;

  Bar({this.data});

  @override
  Widget build(BuildContext context) {
    return Text(data);
  }
}
  1. Использование Флаттера BuildContext

Каждый виджет имеет доступ к BuildContext, Этот класс позволяет одному виджету получать информацию от любого из их предков, используя один из следующих методов:

На самом деле, если есть данные, к которым нужно обращаться много раз, предпочтите inheritFromWidgetOfExactType,

Это использует InheritedWidget; которые являются специфическими видами виджетов, к которым очень быстро получить доступ.

Смотрите Flutter: Как правильно использовать Inherited Widget? для более подробной информации об их использовании


Как примечание стороны, есть третье решение. Который GlobalKey

Я не буду вдаваться в подробности, так как это скорее взлом, чем правильное решение. (см. Строитель против GlobalKey)

Но в основном это позволяет получить состояние / контекст любого виджета вне build вызов. Будь то родители или дети.

на моей стороне я реализовал обратный вызов onChanged.

Например, в моем виджете:

      class ObjectiveCardWidget extends StatefulWidget {
  final Objective? objective;
  final ValueChanged<Objective?>? onChanged;
  ObjectiveCardWidget({this.objective, this.onChanged});
  @override
  State<ObjectiveCardWidget> createState() => _ObjectiveCardWidgetState();
}

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

      widget.onChanged!(newValue);  // newvalue has been set previously

В моем parentWidget я использовал onChanged как обычно:

      ObjectiveCardWidget(
              objective: myObjective,
              onChanged: (value) {
                setState(() {
                  myObjective = value;
                });
              })

Надеюсь, это поможет.

Другие вопросы по тегам