如何将Flutter Slider组件的数值传入关联Firestore数据库的函数
具体修改方案
1. 调整SaveIngredientsProvider逻辑,支持动态传值
我们对原有的updateIngredientCount方法做改造,支持传入要更新的食材数值,你可以按需选择单条更新或者批量更新两种模式:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:wequilschool_app/screens/blend_&_mix/item.dart'; class SaveIngredientsProvider { final CollectionReference blendAndMixDatabase = FirebaseFirestore.instance.collection("BlendandMix"); List<Item> item = []; // 方案1:批量更新所有食材数值,适合所有滑块改完统一提交的场景 Future<void> updateIngredientCount(Map<String, double> ingredients) { return blendAndMixDatabase .doc('H2IbznvLGKYRvCLJSomk') .set({ 'ingredients': ingredients, }, SetOptions(merge: true)) .then((value) => print("食材数量更新成功")) .catchError( (error) => print("更新食材数量失败: $error")); } // 方案2:单独更新某一个食材数值,适合单个滑块修改后即时提交的场景 Future<void> updateSingleIngredient(String ingredientKey, double value) { return blendAndMixDatabase .doc('H2IbznvLGKYRvCLJSomk') .set({ 'ingredients.$ingredientKey': value, }, SetOptions(merge: true)) .then((value) => print("单个食材数量更新成功")) .catchError( (error) => print("更新单个食材数量失败: $error")); } }
小提示:如果需要全局复用同一个Provider实例,建议把SaveIngredientsProvider做成单例,或者用Provider、Riverpod等状态管理工具持有,避免每次调用都新建实例
2. 优化Item组件的状态和传值逻辑
首先修正StatefulWidget的可变参数写法(Flutter要求Widget本身是不可变的,可变状态要放到State类里),同时将滑块值对应传到Provider的更新方法中:
import 'package:flutter/material.dart'; import 'package:wequilschool_app/screens/blend_&_mix/services/save_ingredients_provider.dart'; class Item extends StatefulWidget { final String image; final String name; final String ingredientKey; // 新增:和Firestore字段完全匹配的食材键名,比如almond_butter final double? defaultSaveValue; const Item({ Key? key, required this.image, required this.name, required this.ingredientKey, this.defaultSaveValue, }) : super(key: key); @override _ItemState createState() => _ItemState(); } class _ItemState extends State<Item> { late double _currentValue; // 把可变数值移到State里维护 @override void initState() { super.initState(); _currentValue = widget.defaultSaveValue ?? 0.0; } @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Image.asset( widget.image, width: 70, fit: BoxFit.contain, ), Expanded( child: Text(widget.name, textAlign: TextAlign.center), ), Expanded( child: Slider( value: _currentValue, min: 0, max: 5, divisions: 5, label: _currentValue.toString(), onChanged: (double newValue) { setState(() { _currentValue = newValue; }); // 如果需要滑块拖动时实时同步到Firestore,就打开下面这行注释 // SaveIngredientsProvider().updateSingleIngredient(widget.ingredientKey, _currentValue); }, )), ElevatedButton( onPressed: () { // 点击保存时提交当前食材的数值 SaveIngredientsProvider().updateSingleIngredient(widget.ingredientKey, _currentValue); }, child: const Text('保存食材')), ], ); } }
3. 初始化Item时传入正确的键名
你在构建Item列表的时候,要给每个Item传入和Firestore字段完全对应的ingredientKey参数,示例:
Item( image: 'assets/almond_butter.png', name: '杏仁酱', ingredientKey: 'almond_butter', // 和Firestore里的字段名完全一致 defaultSaveValue: 0, )
如果你需要所有滑块修改完成后统一提交,只需要在上层页面维护所有食材的键值对,点击统一保存按钮时调用updateIngredientCount方法传入完整的map即可。
内容的提问来源于stack exchange,提问作者Chinedu Nwabuisi
相关产品推荐
相关产品推荐

