Упростите приложение Flutter с помощью Provider
Возможно, вам известно о виджетах с сохранением состояния и без состояния, но что, если вы хотите обмениваться данными между несколькими различными виджетами в своем приложении? Вы можете передавать данные между виджетами, но если вы создаете что-то отзывчивое, которое, например, будет меняться в зависимости от размера экрана, вам может потребоваться по-разному структурировать пользовательский интерфейс в зависимости от размера экрана или поворота. Становится действительно сложно управлять состоянием вашего приложения, передавая эти данные в и из ваших виджетов. Вместо этого я предлагаю вам подумать о включении системы менеджера состояний!
И вообще, что такое менеджер состояний?
Управление состоянием - это процесс хранения и обмена данными между различными компонентами. Это позволяет вам хранить данные, относящиеся к состоянию вашего приложения, и извлекать эти данные из любого другого места без необходимости передавать их! Можно сказать, это помогает вам управлять своим состоянием!
Хорошо, а что такое Провайдер?
Провайдер - это пакет, который помогает с управлением состоянием! Короче говоря, он вставляет виджет в ваше дерево виджетов, в котором хранятся значения состояния вашего приложения. Из-за этого любые дочерние элементы этого виджета Provider могут получить доступ к этому состоянию, потому что оно существует в том же дереве виджетов!
Как мне начать работать с Провайдером?
Как и в случае с любым другим пакетом, перед продолжением рекомендуется прочитать документацию по pub.dev. Вот ссылка на провайдера:
A wrapper around InheritedWidget to make them easier to use and more reusable.
Итак, вы читали документацию?
Теперь мы можем импортировать его в наш проект, просто включив его в свой файл pubspec.yaml:
dependencies:
provider: ^5.0.0
Теперь, когда вы импортировали пакет, нам нужно начать его использовать. Чтобы создать поставщик в дереве виджетов, вам необходимо сначала определить лучшее место в дереве виджетов (часто прямо на верхнем уровне для небольших проектов), а затем создать виджет поставщика. Вот пример, когда я решил обернуть все свое приложение в Провайдера, который я назвал MyProvider
void main() {
runApp(ChangeNotifierProvider(
create: (_) => MyProvider(),
child: MyApp()));
}
class MyProvider extends ChangeNotifier {
int counter = 0;
void increment() {
counter++;
notifyListeners();
}
void decrement() {
counter--;
notifyListeners();
}
}
Итак, как мы можем получить к нему доступ и обновить его?
Это просто! Есть несколько разных способов взаимодействия с вашим провайдером. Если вы пытаетесь получить доступ или изменить состояние извне с помощью метода StatelessWidget.build
или State.build
, вы должны получить к нему доступ следующим образом:
Provider.of<MyProvider>(context).increment();
Если вы пытаетесь получить доступ к состоянию в функции сборки, вы можете использовать этот пример:
context.watch<MyProvider>().counter;
В этих двух функциях есть что-то действительно интересное. Они вызовут обновление пользовательского интерфейса! Вызывая notifyListeners()
в конце функций увеличения и уменьшения, мы сообщаем пользовательскому интерфейсу, что его состояние изменилось и его следует перестроить!
Есть еще несколько способов чтения состояния от провайдера, которые я хотел бы затронуть:
context.select((MyProvider myProvider) => myProvider.counter);
Функциональность Provider Select / Selector действительно мощная! Это заставляет ваш виджет следить только за изменениями определенного члена состояния, а не всего объекта состояния. Это становится действительно полезным, если у вас есть несколько разных переменных, в которых вы пытаетесь сохранить состояние, но вы хотите, чтобы ваш виджет заботился только об одной из них!
Selector<MyProvider, int>(
builder: (context, data, child) {
return Text("$data");
},
selector: (_, myProvider) => myProvider.counter,
),
Верно! Если вы создаете это непосредственно в функции сборки и у вас есть виджеты, зависящие от этих данных, вы можете создать соответствующие виджеты, которые эквивалентны приведенным выше операторам контекста! В данном случае я решил сделать пример виджета «Селектор».
Наконец, если вы отлаживаете, вы можете увидеть значения всех ваших провайдеров в Flutter DevTools!
Я также хочу упомянуть, что есть более новый пакет управления состоянием под названием Riverpod. Многие считают его «Провайдером 2.0» и предлагают несколько потрясающих улучшений. Я скоро напишу о Riverpod!