Flutter:从sharedPreferences-list中生成具有立即可见效果的列表



我正在努力学习扑动和建立一个小的"购物清单应用程序"。为此,我将购物清单的状态保存到sharedPreferences中以供以后使用。通过这种方式,我能够在关闭和打开应用程序后恢复相同的列表,但只有在"触发重建"(?)之后,开始在文本字段中键入一些东西,使用以下代码:

class _ItemChecklistState extends State<ItemChecklist> {
final List<ShoppingItem> _items = [];
final _itemNameController = TextEditingController();
final _amountController = TextEditingController()..text = '1';
final Map<int, bool> checkedMap = new Map();
bool _isComposing = false;
...
@override
Widget build(BuildContext context) {
// calling the method to "preload" my state from the shared preferences
_loadPrefs();
return Scaffold(
appBar: AppBar(
title: Text('Shopping List'),
actions: <Widget>[
IconButton(
onPressed: () => _removeCheckedItems(),
icon: Icon(Icons.remove_done)),
IconButton(
icon: const Icon(Icons.remove_circle_outline),
tooltip: 'Remove all items',
onPressed: () => _removeAllItems(),
),
],
),
body: Column(children: [
Flexible(
child: ListView.builder(
itemBuilder: (_, int index) => _items[index],
padding: EdgeInsets.all(8.0),
itemCount: _items.length,
),
),
Divider(height: 1.0),
Container(child: _buildTextComposer())
]));
}
...
// the method I use to "restore" my state
void _loadPrefs() async {
String key = 'currentItemList';
SharedPreferences prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey(key)) { return; }
_items.clear();
checkedMap.clear();
Map stateAsJson = jsonDecode(prefs.getString(key));
final itemsKey = 'items';
final checkedMapKey = 'checkedMap';
List items = stateAsJson[itemsKey];
Map checkedMapClone = stateAsJson[checkedMapKey];
for (Map item in items){
ShoppingItem newItem = ShoppingItem(
id: item['id'],
name: item['name'],
amount: item['amount'],
removeFunction: _removeItemWithId,
checkedMap: checkedMap,
saveState: _saveListToSharedPrefs,
);
_items.add(newItem);
checkedMap.putIfAbsent(newItem.id, () => checkedMapClone[newItem.id.toString()]);
}
}
...
}

现在加载状态和设置列表工作正常,所以_items列表被正确更新,以及checkedMap,但ListView不包含相应的数据。例如,我如何触发重建?立即或确保"第一";ListView的构建已经包含正确的状态?谢谢:)

当你的UI依赖于异步任务时,你必须使用FutureBuilder

Future<List<ShoppingItem>> _getShoppingItems;
@override
void initState() {
_getShoppingItems = _loadPrefs();
super.initState();
}
@override
Widget build(BuildContext context) {
FutureBuilder<List<ShoppingItem>>(
future: _getShoppingItems,
builder: (context, snapshot) {
// Data not loaded yet
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
// Data loaded
final data = snapshot.data;
return ListView(...);
}
}
);

更多信息:https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

最新更新