【问题标题】:Create ListView with infinite scrolling by provider: setState() or markNeedsBuild() called during build通过提供者创建无限滚动的 ListView:在构建期间调用 setState() 或 markNeedsBuild()
【发布时间】:2021-06-11 05:59:06
【问题描述】:

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

在 itemBuilder 中调用 notifyListener() 时,我收到错误“setState() 或 markNeedsBuild() 在构建期间调用”。

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

我的问题是:

  • 是否有在构建之后或之前调用 notifyListener() 的解决方法?
  • 如果这甚至不是合适的方法,那么使用 Provider 将内容添加到 ListView 以实现无限滚动的最佳方法是什么?

这不是 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();
  }
}

【问题讨论】:

标签: flutter provider flutter-change-notifier


【解决方案1】:

从 addSuggestions() 中移除 notifyListeners();

这是因为每次滚动发生时都会构建 ListView。您不需要使用 notifyListeners 来重建 a widget that rebuilds by itself 内的小部件。

【讨论】:

    猜你喜欢
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    • 2018-05-15
    • 2021-08-11
    • 2020-10-05
    • 2021-11-05
    相关资源
    最近更新 更多