#flutter #state-management
Вопрос:
Я получаю данные с сервера и сохраняю данные в списке, затем передаю некоторую часть этих данных классу поставщика, который некоторые другие виджеты прослушивают этот класс поставщика, но я не знаю, почему при запуске приложения он выдает мне вышеуказанную ошибку, хотя приложение запускается, но пользовательский интерфейс не обновляется при изменении данных. Кажется, что он не прислушивается к этому. Но я уверен, что добавил к этому метод уведомления слушателей.
Вот мой код: класс поставщика:
import 'package:flutter/material.dart';
class EmpAndState with ChangeNotifier {
final String empId;
String stateId;
EmpAndState({@required this.empId, this.stateId = "1"});
}
class EmpsAstates with ChangeNotifier {
List<EmpAndState> _items = [];
List<EmpAndState> get items {
return [..._items];
}
void addAll(List<String> empIdes) {
final eIds = empIdes.map((e) => EmpAndState(empId: e)).toList();
_items = eIds;
notifyListeners();
}
// void addItem(String eId, String stId) {
// _items.add(EmpAndState(empId: eId, stateId: stId));
// notifyListeners();
// }
void updateItem(String eId, String stId) {
_items[_items.indexWhere((es) => es.empId == eId)] =
EmpAndState(empId: eId, stateId: stId);
notifyListeners();
}
EmpAndState findById(String eId) {
return _items.firstWhere((es) => es.empId == eId);
}
}
Класс слушателя:
import 'package:Attendece/provider/empAstate.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../provider/employeeAtypes.dart';
class ListTileRow extends StatelessWidget {
static const IconData cancel_outlined =
IconData(0xe0c9, fontFamily: 'MaterialIcons');
Widget build(BuildContext context) {
Employee emp = Provider.of<Employee>(context);
final empAsta = Provider.of<EmpsAstates>(context);
final eas = empAsta.findById(emp.employeeId);
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
icon: eas.stateId == "1"
? Icon(Icons.check_circle, color: Color(0xff507ce0))
: Icon(Icons.check_circle_outline),
onPressed: () {
if (eas.stateId != "1") {
eas.stateId = "1";
} else {
eas.stateId = "2";
}
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
}),
IconButton(
icon: eas.stateId == "2"
? Icon(Icons.clear, color: Colors.red)
: Icon(Icons.clear),
onPressed: () {
if (eas.stateId != "2") {
eas.stateId = "2";
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
} else {
eas.stateId = "1";
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
}
}),
IconButton(
icon: eas.stateId == "3"
? Icon(Icons.airline_seat_flat, color: Color(0xff507ce0))
: Icon(Icons.airline_seat_flat),
onPressed: () {
if (eas.stateId != "3") {
eas.stateId = "3";
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
} else {
eas.stateId = "1";
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
}
}),
IconButton(
icon: eas.stateId == "5"
? Icon(Icons.home, color: Color(0xff507ce0))
: Icon(Icons.home),
onPressed: () {
if (eas.stateId != "5") {
eas.stateId = "5";
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
} else {
eas.stateId = "1";
emp.notifyListeners();
empAsta.updateItem(emp.employeeId, eas.stateId);
}
}),
],
);
}
}
Ответ №1:
Вам необходимо инициализировать поставщика в точке входа вашего приложения
предоставьте оболочку вокруг InheritedWidget, чтобы сделать их более простыми в использовании и более многоразовыми.
вы не можете получить к нему доступ до его инициализации
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<MyProvider>(
create: (context) => MyProvider()),
], child: MaterialApp(....
также измените with ChangeNotifier
на extends ChangeNotifier
Комментарии:
1. Я делал это раньше, и мой основной урок похож на этот.
2. вместо использования final для использования провайдером var попробуйте запустить flutter clean, а затем повторно запустить приложение
3. Консоль показывает ошибку в классе поставщика, в котором я вызвал notifyListeners() в методе addAll ().