Flutter查询SQLite显示`Instance of 'Future<int>'`的解决方法
解决Flutter SQLite异步查询价格显示问题
问题根源
SQLite查询是异步操作,直接调用会返回Future对象,所以界面会显示Instance of 'Future<int>';而Widget构建方法必须返回Widget类型,不能返回Future,给_buildItemCards加async/await后返回的是Future<dynamic>,自然会触发类型不匹配错误。
正确解决方案
方案1:用FutureBuilder处理单条数据异步加载
把价格查询逻辑抽成独立异步方法,在Widget中用FutureBuilder包裹价格显示区域,它会自动处理异步状态(加载中、成功、错误):
// 抽离价格查询方法 Future<int> getItemPrice(int itemId) async { final db = await _database; // 替换成你的SQLite数据库实例 final result = await db.query( 'prices', where: 'item_id = ?', whereArgs: [itemId], columns: ['price'], ); return result.isNotEmpty ? result.first['price'] as int : 0; } // 构建商品卡片的方法 Widget _buildItemCards(Item item) { return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('商品名称:${item.name}'), // 用FutureBuilder处理异步价格 FutureBuilder<int>( future: getItemPrice(item.id), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Text('加载价格中...'); } else if (snapshot.hasError) { return const Text('获取价格失败'); } else { return Text('商品价格:${snapshot.data}'); } }, ), ], ), ), ); }
方案2:预加载所有价格缓存(性能更优)
如果是列表展示商品,建议在页面初始化时一次性查询所有商品价格并存到Map中,避免每个Item重复发起数据库请求:
class _InventoryPageState extends State<InventoryPage> { List<Item> _items = []; Map<int, int> _itemPriceMap = {}; bool _isLoading = true; @override void initState() { super.initState(); _loadAllData(); } // 一次性加载商品列表和所有价格 Future<void> _loadAllData() async { final db = await _database; // 加载商品列表 final itemResults = await db.query('items'); _items = itemResults.map((row) => Item.fromMap(row)).toList(); // 加载所有价格并缓存 final priceResults = await db.query('prices'); _itemPriceMap = { for (var row in priceResults) row['item_id'] as int: row['price'] as int }; setState(() => _isLoading = false); } @override Widget build(BuildContext context) { if (_isLoading) { return const Center(child: CircularProgressIndicator()); } return ListView.builder( itemCount: _items.length, itemBuilder: (context, index) { final item = _items[index]; final price = _itemPriceMap[item.id] ?? 0; return Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('商品名称:${item.name}'), Text('商品价格:$price'), ], ), ), ); }, ); } }
关键注意点
- 永远不要让Widget构建方法(如
build、itemBuilder)返回Future,必须用FutureBuilder或预加载数据的方式处理异步逻辑 - 预加载缓存的方式更适合列表场景,能减少数据库IO次数,提升界面流畅度
内容的提问来源于stack exchange,提问作者extxuser
相关产品推荐
相关产品推荐

