#flutter #flutter-layout #flutter-dependencies #flutter-web #flutter-animation
Вопрос:
Проблема, с которой я сталкиваюсь, заключается в том, что я подключаю свой пользовательский интерфейс к серверной части с помощью websocket, используя метод подписки(клиент graphql). Это означает, что между моим пользовательским интерфейсом и бэкендом существует связь. Я храню данные, полученные из бэкенда, в локальном хранилище Из локального хранилища, я получаю эти данные,
Всякий раз, когда я получаю данные от бэкенда, они должны автоматически отражаться в пользовательском интерфейсе. Для отражения изменений в пользовательском интерфейсе я использую пакет поставщика управления состоянием.Что я должен сделать, чтобы мой виджет перестроился после прослушивания изменений, которые я внес с помощью пакета поставщика;
Ответ №1:
class MyNotifier extends ChangeNotifier {
bool _listenableValue = false;
bool get listenableValue => _listenableValue
MyNotifier.instance();
void setValue(){
_listenableValue = !_listenableValue;
notifyListeners();
}
}
...
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyNotifier>(
create: (context) => MyNotifier.instance(),
builder: (context, child){
return Column(
children: [
StaticWidget(),
//This text widget will rebuild when value is changed
Selector<MyNotifier, bool>(
selector: (_, notifier) => notifier.listenableValue,
builder: (_, value, __) => Text('$value');
),
//Change value with button
IconButton(
icon: //icon
onPressed: (){
context.read<MyNotifier>().setValue();
},
);
]
);
}
);
}
Не пользуйся . Consumer
Потребитель перестроит все виджеты при изменении данных. Это плохая ситуация для производительности.
Selector
это лучшее, на мой взгляд.
Ответ №2:
Если у вас есть свое состояние в индикаторе изменений, например:
class MyState extends ChangeNotifier{
addStorage(Map<String, String> data) {...}
getAllDataFromStorage() {...}
}
Затем вы можете перестроить свой пользовательский интерфейс, просто обернув нужные виджеты в Consumer
.
Consumer<MyState>(builder: (context, state) {
return Container(
padding: EdgeInsets.only(top: 10),
child: LayoutBuilder(builder: (context, constraints) {
if (screenLayout >= 1024) {
return desktopWidget(context, visitsList);
} else if (screenLayout >= 768 amp;amp; screenLayout <= 1023) {
return tabletWidget(context, visitsList);
} else {
return mobileWidget(context, visitingsList, screenLayout);
}
})},
);
Обратите внимание, что где-то над этим фрагментом у вас должна быть ChangeNotifierProvider
MyState
вставка в дерево виджетов.
Для действительно подробного и полного руководства взгляните на Простое управление состоянием
Комментарии:
1. Это исключение. setState() или markNeedsBuild вызывается во время сборки
Ответ №3:
**best way to listen changes in provider its to make getter and setter i will show you example below**
class ContactProvider with ChangeNotifier {
bool isBusy = true;
bool get IsBusy => isBusy;
set IsBusy(bool data) {
this.isBusy = data;
notifyListeners();
}
void maketru(){
IsBusy=false;
}
}
и теперь вы можете использовать это context.read<ContactProvider>().Isbusy;
Комментарии:
1. хорошо, Мухаммад Арбаз Зафар ,это полезно.