I am new to Flutter and this is my first question on Stackoverflow. Please let me know if I need to provide more context or details for my question.
In my app the user can navigate to a page with a two-level nested list widgets. When there are more than 20 items in the lowest level list, it takes a few seconds for Flutter to render it before the page is pushed by the Navigator and shown to the user, which makes it feel like the app is frozen for a moment, which is what I dislike a lot.
I’ve tried to use FutureBuilder to build the widget tree in an async function and show a CircularProgressIndicator while the widgets are building. However, it doesn’t work, the future builder just waits for the connection state to be done and no progress indicator is displayed. Below is the simplified code that replicates the issue – no progress indicator is showing while the widgets are building. I need to use the cacheExtent property in the List.builder to improve the scrolling smoothness, as each item on the list has text fields and inkWell which causes a laggy scrolling when not using the cache extent. I do not need a lazy loading here as the list length is fixed and not that large. However, I can see that the future builder issue is not related to the cache extent.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Future<Widget> _buildFutureWidget() async {
List<Widget> list = List.generate(
1000, (index) => Text('List item #' + (index + 1).toString()));
return Scaffold(
body: ListView.builder(
itemCount: list.length,
cacheExtent: 999999999999999,
itemBuilder: (context, i) {
print('Building item ${list[i]}');
return ListTile(title: list[i]);
},
),
);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Widget>(
future: _buildFutureWidget(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.none:
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
return snapshot.data;
}
},
);
}
}
Can you please help me to find what went wrong with my code and how to display the progress indicator while the widgets are being built?
Any insight is much appreciated!