我正在尝试使用Google Maps插件编写一个简单的Flutter应用。我需要使用多个BLoC / ChangeNotifier对象来管理屏幕上显示的对象。
当我在ChangeNotifier上调用notifyListeners()
时,问题就出现了。调用notifyListeners()
的方法完成其执行,然后应用完全冻结(没有小部件更新,无法与现有小部件进行交互)。
我试图了解问题出在哪里:我唯一了解的是CompaniesData
(这是引起问题的ChangeNotifier)为空时,它可以正常工作。
class CompaniesData extends ChangeNotifier {
Map<MarkerId, Company> _companiesMap;
set companies(Set<Company> companies) {
_companiesMap = companies != null
? Map.fromIterable(
companies,
key: (company) => MarkerId(company.id.toString()),
value: (company) => company,
)
: null;
notifyListeners();
;
}
bool get available => _companiesMap != null;
Company companyWithId(MarkerId id) => available ? _companiesMap[id] : null;
Map<MarkerId, Company> get companiesIfAvailable =>
available ? _companiesMap : Map();
Iterable<Company> companiesFromIds(BuildContext context, Set<int> ids) {
Set<int> idsCopy = Set.from(ids);
return companiesIfAvailable.entries
.where((entry) => idsCopy.remove(entry.value.id))
.map<Company>((entry) => entry.value);
}
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Consumer<CompaniesData>(
builder: (context, data, child) {
return BlocBuilder(
bloc: BlocProvider.of<ShownCompaniesBloc>(context),
builder: (context, shownCompaniesState) {
return BlocBuilder(
bloc: BlocProvider.of<FavoriteCompaniesBloc>(context),
builder: (context, favoriteCompaniesState) {
return BlocBuilder(
bloc: BlocProvider.of<MapPropertiesBloc>(context),
builder: (context, mapPropertiesState) {
CompaniesData data =
Provider.of<CompaniesData>(context, listen: false);
// ...
如您所见,构建方法包含多个嵌套的BLoC / Consumer对象。
@override
void initState() {
_fetchCompanies();
super.initState();
}
void _fetchCompanies() {
findUser().then((location) {
Set<Company> companies = Set.from([Company.fake()]);
// CompaniesData.companies is a setter, which calls
// notifyListeners
_companiesData.companies = companies;
});
}
我没有收到错误消息,异常,给findUser().then()
的回调执行结束后,我的应用程序就死了。
编辑:
我稍微更改了代码,发现问题不是notifyListeners
(或者至少不是现在)。
final Completer<Map<MarkerId, Company>> _companiesData = Completer();
_AeroMainViewState() {
findUser()
.then(_fetchCompanies)
.then((companies) => _companiesData.complete(Map.fromIterable(
companies,
key: (company) => MarkerId(company.id.toString()),
value: (company) => company,
)));
}
Future<Set<Company>> _fetchCompanies(LatLng location) async =>
Set.from([Company.fake()]);
// ...
child: FutureBuilder<Map<MarkerId, Company>>(
future: _companiesData.future,
builder: (context, snapshot) {
// this builder function isn't called at all
// when the Completer _companiesData is completed
if (snapshot.connectionState == ConnectionState.done) {
return Provider<Map<MarkerId, Company>>.value(
value: snapshot.data,
child: // ...
} else {
return Center(child: CircularProgressIndicator());
}
}),
// ...
删除ChangeNotifier不能解决问题。
答案 0 :(得分:0)
我将我的错误发布给以后参考。我在上课时是这样做的:
action(s)
由于Stream可能包含无限多个对象,因此对该流的订阅阻塞了主线程(也是唯一线程)。