所以我正试图通过“未来通话”在我的提供商中建立一个列表。
到目前为止,我在下面有以下ChangeNotifier类:
class MainProvider extends ChangeNotifier {
List<dynamic> _list = <dynamic>[];
List<dynamic> get list => _list;
int count = 0;
MainProvider() {
initList();
}
initList() async {
var db = new DatabaseHelper();
addToList(Consumer<MainProvider>(
builder: (_, provider, __) => Text(provider.count.toString())));
await db.readFromDatabase(1).then((result) {
result.forEach((item) {
ModeItem _modelItem= ModeItem.map(item);
addToList(_modelItem);
});
});
}
addToList(Object object) {
_list.add(object);
notifyListeners();
}
addCount() {
count += 1;
notifyListeners();
}
}
但是,只要我使用 list 值,就会发生这种情况:
注意:
我真正关心的是,在初始加载时,我的列表值没有 按预期正确初始化所有值
希望你们可以在这一方面帮助我。谢谢。
更新:下面显示了我如何使用上面的ChangeNotifierClass
class ParentProvider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<MainProvider>(
create: (context) => MainProvider(),
),
],
child: ParentWidget(),
);
}
}
class ParentWidget extends StatelessWidget {
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
@override
Widget build(BuildContext context) {
var mainProvider = Provider.of<MainProvider>(context);
buildItem(BuildContext context, int index, Animation animation) {
print('buildItem');
var _object = mainProvider.list[index];
var _widget;
if (_object is Widget) {
_widget = _object;
} else if (_object is ModelItem) {
_widget = Text(_object.unitNumber.toString());
}
return SizeTransition(
key: ValueKey<int>(index),
axis: Axis.vertical,
sizeFactor: animation,
child: InkWell(
onTap: () {
listKey.currentState.removeItem(index,
(context, animation) => buildItem(context, index, animation),
duration: const Duration(milliseconds: 300));
mainProvider.list.removeAt(index);
mainProvider.addCount();
},
child: Card(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: _widget,
),
),
),
);
}
return Scaffold(
appBar: AppBar(),
body: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(32.0),
child: mainProvider.list == null
? Container()
: AnimatedList(
key: listKey,
initialItemCount: mainProvider.list.length,
itemBuilder:
(BuildContext context, int index, Animation animation) =>
buildItem(context, index, animation),
),
),
),
);
}
}
答案 0 :(得分:2)
您正在从StatelessWidget
检索提供者。因此,ChangeNotifier
无法触发窗口小部件进行重建,因为没有状态可以重建。您必须将ParentWidget
转换为StatefulWidget
,或者需要使用Consumer
而不是Provider.of
来获得提供者:
class ParentWidget extends StatelessWidget {
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
@override
Widget build(BuildContext context) {
return Consumer<MainProvider>(
builder: (BuildContext context, MainProvider mainProvider, _) {
...
}
);
}
顺便说一句,您使用提供程序的方法是将MainProvider
添加到其提供程序,然后从其直接子级中检索它。如果这是您唯一要检索MainProvider
的地方,这将使提供程序模式变得多余,因为您可以轻松地在ParentWidget
中声明它,甚至可以使用{{1}获取图像列表}。使用提供程序是朝着适当的状态管理迈出的重要一步,但也要避免过度设计您的应用程序。