通过提供者创建具有无限滚动的 ListView:在构建期间调用的 setState() 或 markNeedsBuild()
Create ListView with infinite scrolling by provider: setState() or markNeedsBuild() called during build
我正在尝试创建 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();
}
}
从 addSuggestions() 中删除 notifyListeners();
这是因为每次发生滚动时都在构建ListView。您不需要使用 notifyListeners 来重建 a widget that rebuilds by itself.
内的小部件
我正在尝试创建 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();
}
}
从 addSuggestions() 中删除 notifyListeners();
这是因为每次发生滚动时都在构建ListView。您不需要使用 notifyListeners 来重建 a widget that rebuilds by itself.
内的小部件