Provider 调用 notifyListeners() 时 Flutter View 不更新视图

Posted

技术标签:

【中文标题】Provider 调用 notifyListeners() 时 Flutter View 不更新视图【英文标题】:Flutter View does not update view while Provider call notifyListeners() 【发布时间】:2020-11-19 14:15:00 【问题描述】:

我想在调用提供程序函数时查看更新列表项。但它不起作用。 在将普通视图更改为FutureBuilder 之前,它起作用了。我尝试改用StreamBuilder,也不起作用。

我该如何解决这个问题?

这里是提供者:

class SelectArtistProvider extends ChangeNotifier 
  List<Map> artists = [];
  ...
  Future initArtistListVM() async  //for Future Builder
    var allArtists =
        await Firestore.instance.collection('artists').getDocuments();

    List list = allArtists.documents
        .map((artist) => 
              'id': artist.documentID,
              'name': artist.data['name'],
              'image': "artist.data['image'],
              'selected': "false",
            )
        .toList();
    artists = list;
    notifyListeners();
    return artists;
  

  void toggleSelected(Map item, int index) 
    artists[index]['selected'] = !item['selected'];
    notifyListeners();
  

查看

// list view
class SelectArtist extends StatelessWidget 
  Widget build(BuildContext context) 
    final selectArtistProvider = Provider.of<SelectArtistProvider>(context);
    return FutureBuilder(
      future: selectArtistProvider.initArtistListVM(), // initial data from api
      builder: (context, snapshot) 
        return ListView.builder(
          ...
          child: ArtistItem(index, selectArtistProvider.artists[index])


// item view
class ArtistItem extends StatelessWidget 
  final int index;
  final Map artist;
  Widget build(BuildContext context) 
    final selectArtistProvider = Provider.of<SelectArtistProvider>(context);
      return GestureDetector(
        onTap: () => selectArtistProvider.toggleSelected(artist, index),
        child: 
          ...
          Visibility(
            visible: artist['selected'],
            child: SomeWidget()
            ...

// root view to place providers
class InitialProviders extends StatelessWidget 

  @override
  Widget build(BuildContext context) 
    return MultiProvider(
        providers: [
          ...
          ChangeNotifierProvider(create: (_) => SelectArtistProvider()),
        ],
        child: ...

【问题讨论】:

我注意到,每当 ArtistItem 调用 toggleSelected() 时都会调用 FutureBuilder,因此每次 toggleSelected() 更新 artists 时都会覆盖 artists。我能为它做些什么? 【参考方案1】:

解决了这个问题!

更改initArtistListVM() 的某些部分。

if (artists.isEmpty) 
    artists = list;
    notifyListeners();

【讨论】:

以上是关于Provider 调用 notifyListeners() 时 Flutter View 不更新视图的主要内容,如果未能解决你的问题,请参考以下文章

提供者 NotifyListeners 不更新消费者

如何专门为 Flutter 中的 Class 方法构建 Provider 包的 Consumer Widget?

在 deactivate() 中调用 notifyListeners() 会导致错误 - Flutter

消费者未使用 notifyListeners() 进行更新

Flutter:`notifyListeners`不更新列表

如何在带有 Provider 的 ListView 中返回 Future<double>?