I am trying to create ListView where items are built while the screen is being scrolled. I am trying to add content by using provider.
I get an error "setState() or markNeedsBuild() called during build" when calling notifyListener() inside itemBuilder.
I know the reason is because notifyListener() is called during ListView is built.
My questions are:
- is there a workaround to call notifyListener() after or before build?
- if this is not even an appropriate approach, what is the best approach to add content to ListView for infinite scrolling by using Provider?
This is not a duplicate of this post because his ListView widget doesn't have to be built over and over again as scroll happens.
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();
}
}