Есть много вещей, которые вы делаете неправильно здесь. Вы должны понимать, что Поставщик может предоставлять доступ ко всем виджетам ниже. Кроме того, это также поможет другим понять Flutter
и Provider
немного больше.
Сначала , убедитесь, что вы открываете объект ButtonData где-то над строкой, где Вы хотите использовать значение.
Примерно так:
//You can use this in the build method, and wrap it on top of your page Scaffold.
//@override
//Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => ButtonData(),
child: Scaffold(
appBar: _appBar(),
body: _body(),
),
);
//}
Второй , способ, которым вы используете для получения кнопок в виджете Row
очень плохо, когда вы хотите использовать свой объект несколько раз, как в вашем коде, вы должны использовать виджет Consumer
, чтобы представить свои ButtonData как переменную и использовать это вместо всей строки: Provider.of<ButtonData>(context)
.
Проверьте это:
//WRONG WAY
new Row(children: [
buildButton(Provider.of<ButtonData>(context).getNumberOne(Provider.of<ButtonData>(context).selectedButton.type)),
buildButton(Provider.of<ButtonData>(context).getNumberTwo(Provider.of<ButtonData>(context).selectedButton.type)),
buildButton(Provider.of<ButtonData>(context).getNumberThree(Provider.of<ButtonData>(context).selectedButton.type)),
])
//CORRECT WAY
Consumer<ButtonData>(
builder: (BuildContext context, ButtonData buttonData, Widget child) => Row(
children: <Widget>[
buildButton(buttonData.getNumberOne(buttonData.selectedButton.type)),
buildButton(buttonData.getNumberTwo(buttonData.selectedButton.type)),
buildButton(buttonData.getNumberThree(buttonData.selectedButton.type)),
],
),
);
Также, если вы выбираете значение Provider
в вашей функции initState
, это означает, что вы выбираете ваше значение ВНЕ дерева виджетов. (Все, что вы возвращаете в функции build
, - это ваше дерево виджетов). Чтобы получить значение за пределами дерева виджетов, используйте это.
///WRONG
Provider.of<ButtonData>(context).selectedButton = Provider.of<ButtonData>(context).setSelectedItem(Provider.of<ButtonData>(context).buttons.first);
///CORRECT
///You need to set `listen` to false.
Provider.of<ButtonData>(context, listen: false).selectedButton = Provider.of<ButtonData>(context, listen: false).setSelectedItem(Provider.of<ButtonData>(context, listen: false).buttons.first);
///BETTER
ButtonData buttonData = Provider.of<ButtonData>(context, listen: false);
buttonData.selectedButton = buttonData.setSelectedItem(buttonData.buttons.first);
Еще один совет ... Вам не нужно использовать ключевое слово new
, если вы видели это в уроках, потому что эти уроки очень старые и используют Dart 1, в настоящее время в Dart 2 ключевое слово new
больше не требуется.
Надеюсь, это поможет !!
ОБНОВЛЕНИЕ:
В вашем ButtonData
классе также отсутствуют объявления.
Пояснения к ошибкам, которые вы упомянули в комментарии:
//If you want to use the following:
Provider.of<ButtonData>(context, listen: false).selectedButton = xyz;
//You need to declare a setter named `selectedButton` in your ButtonData
// class. Like so:
set selectedButton(Button button) {
_selectedButton = button;
notifyListeners();
}
//Currently, in your ButtonData class, you have not declared a setter,
// instead you created a method there for updating the value.
//This one.
void setSelectedItem(Button s) {
_selectedButton = s;
notifyListeners();
}
//If you want to use this method for updating your `selectedButton` value,
// you can use the following line of code.
Provider.of<ButtonData>(context, listen: false).setSelectedItem(xyz);