通过提供者创建具有无限滚动的 ListView:在构建期间调用的 setState() 或 markNeedsBuild()

Create ListView with infinite scrolling by provider: setState() or markNeedsBuild() called during build

我正在尝试创建 ListView,在滚动屏幕时构建项目。我正在尝试使用提供商添加内容。

在 itemBuilder 中调用 notifyListener() 时出现错误“在构建期间调用了 setState() 或 markNeedsBuild()”。

我知道原因是因为在构建 ListView 期间调用了 notifyListener()。

我的问题是:

这不是 this post 的副本,因为他的 ListView 小部件不必在滚动时一遍又一遍地构建。

my_app.dart

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
import 'package:provider/provider.dart';
import 'suggestions.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => Suggestions(),
        ),
      ],
      child: MaterialApp(
        title: 'Welcome to Flutter',
        theme: ThemeData(
          primaryColor: Colors.white,
        ),
        home: RandomWords(),
      ),
    );
  }
}

class RandomWords extends StatelessWidget {
  final _biggerFont = TextStyle(fontSize: 18.0);

  void _addSuggestions(BuildContext context) {
    Provider.of<Suggestions>(context, listen: false).addSuggestions();
  }

  @override
  Widget build(BuildContext context) {
    var suggestions = Provider.of<Suggestions>(context).getSuggestions;
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
        actions: [
          IconButton(icon: Icon(Icons.list), onPressed: () {}),
        ],
      ),
      body: _buildSuggestions(suggestions),
    );
  }

  Widget _buildSuggestions(suggestions) {
    return ListView.builder(
        padding: EdgeInsets.all(16.0),
        itemBuilder: /*1*/ (context, i) {
          if (i.isOdd) {
            return Divider(); /*2*/
          }

          final index = i ~/ 2; /*3*/
          if (index >= suggestions.length) {
            _addSuggestions(context);
          }
          return _buildRow(suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    return ListTile(
      title: Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: Icon(
        Icons.favorite_border,
        color: null,
      ),
    );
  }
}

suggestions.dart

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

class Suggestions extends ChangeNotifier {
  var _suggestions = <WordPair>[];

  get getSuggestions {
    return _suggestions;
  }

  void addSuggestions() {
    _suggestions.addAll(generateWordPairs().take(10));
    notifyListeners();
  }
}

从 addSuggestions() 中删除 notifyListeners();

这是因为每次发生滚动时都在构建ListView。您不需要使用 notifyListeners 来重建 a widget that rebuilds by itself.

内的小部件