我试图在 listView 构建器中显示我在初始化构造函数时加载的列表。 这现在不起作用,因为 listView 在构造函数完成加载我的列表之前运行。
怎么办?
我的通知者:
class TablesNotifier with ChangeNotifier {
// Services
// ---------------------------------------------------------------------------
final jsonSelectorService = locator<JsonSelectorService>();
// Variables
// ---------------------------------------------------------------------------
List<AltitudeModel> altitudes;
// Constructor
// ---------------------------------------------------------------------------
TablesNotifier(){
_initialise();
}
// Initialisation
// ---------------------------------------------------------------------------
Future _initialise() async{
print('--- initialise');
altitudes = await jsonSelectorService.altitudes();
}
}
我的屏幕:
class TableScreen extends StatelessWidget {
final String title;
TableScreen({Key key, @required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context)
{
var _tableProvider = Provider.of<TablesNotifier>(context);
return ListView.builder(
itemCount: _tableProvider.altitudes.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${_tableProvider.altitudes[index]}'),
);
},
);
}
}
答案 0 :(得分:1)
您可以在下面复制粘贴运行完整代码
我使用 7 秒延迟来模拟 jsonSelectorService
第 1 步:您可以检查 _tableProvider.altitudes == null
并返回 CircularProgressIndicator()
或 ListView
第 2 步:当 altitudes
数据准备好时调用 notifyListeners()
代码片段
Future _initialise() async {
print('--- initialise');
await Future.delayed(Duration(seconds: 7), () {});
altitudes = [
AltitudeModel(title: "1"),
AltitudeModel(title: "2"),
AltitudeModel(title: "3"),
AltitudeModel(title: "4"),
AltitudeModel(title: "5")
];
notifyListeners();
}
Widget _buildBody(BuildContext context) {
var _tableProvider = Provider.of<TablesNotifier>(context);
return _tableProvider.altitudes == null
? Center(child: CircularProgressIndicator())
: ListView.builder(
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => TablesNotifier(),
builder: (context, child) => MaterialApp(
home: TableScreen(),
),
);
}
}
class AltitudeModel {
String title;
AltitudeModel({this.title});
}
class TablesNotifier with ChangeNotifier {
// Services
// ---------------------------------------------------------------------------
//final jsonSelectorService = locator<JsonSelectorService>();
// Variables
// ---------------------------------------------------------------------------
List<AltitudeModel> altitudes;
// Constructor
// ---------------------------------------------------------------------------
TablesNotifier() {
_initialise();
}
// Initialisation
// ---------------------------------------------------------------------------
Future _initialise() async {
print('--- initialise');
await Future.delayed(Duration(seconds: 7), () {});
altitudes = [
AltitudeModel(title: "1"),
AltitudeModel(title: "2"),
AltitudeModel(title: "3"),
AltitudeModel(title: "4"),
AltitudeModel(title: "5")
];
notifyListeners();
}
}
class TableScreen extends StatelessWidget {
final String title;
TableScreen({Key key, @required this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
var _tableProvider = Provider.of<TablesNotifier>(context);
return _tableProvider.altitudes == null
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _tableProvider.altitudes.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${_tableProvider.altitudes[index].title}'),
);
},
);
}
}
答案 1 :(得分:1)
最快的方法是使用 FutureBuilder
确保 altitudes
列表在发送到 UI 之前已完全加载。你可以这样做:
Widget _buildBody(BuildContext context) {
var _tableProvider = Provider.of<TablesNotifier>(context);
return FutureBuilder<List<AltitudeModel>>(
initialData: <AltitudeModel>[] // Here you can even set the initial data of your list
future: _tableProvider.altitudes,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Container(child: Center(child: CircularProgressIndicator()));
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${snapshot.data[index]}'),
);
},
);
}
);
}