我想要实现的是,当我在 WelcomeScreen 类中添加新食物时,我希望在 FoodList 类中重新呈现我的食物对象列表。下面我有两个类的相关代码。我的问题似乎是当我添加一个新对象时 FoodList 类没有呈现!?我尝试对 FoodList 使用 ChangeNotifierProvider,并从 WelcomeScreen 调用 setFoodList 方法,该方法调用 notifyListeners 方法,但它似乎不起作用。
代码逻辑应该是应用程序从一开始就加载应用程序中的图像,然后用户应该能够使用图像选择器添加图像,这些图像也被保存到数据库中。
非常感谢任何想法!
我的相关代码是。
FoodList类:
getChildrenOfFoodBrainList(List<Food> foodList) {
//final foodList = Provider.of<FoodBrain>(context).getFoodList();
return List.of(foodList.map((food) => ImageCircle(
image: food.imageDb == null ? food.fileName! : food.imageDb!,
displayName: food.displayName!,
text: food.text,
)));
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => FoodBrain(),
child: Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Consumer<FoodBrain>(builder: (context, foodBrain, _) {
return Column(children: <Widget>[
AppBar(
backgroundColor: Colors.grey,
actions: [
IconButton(onPressed: () {}, icon: Icon(Icons.search)),
],
),
Expanded(
child: Center(
child: GridView.count(
primary: false,
crossAxisCount: 4,
shrinkWrap: true,
children:
getChildrenOfFoodBrainList(foodBrain.getFoodList()),
),
),
),
欢迎屏幕类:
Future<File?> saveImageToDatabase(_displayName, imageFile) async {
final file = File(imageFile!.path);
String imgString = Utility.base64String(file.readAsBytesSync());
//Create new food object
setState(() {
Food food = new Food(
displayName: _displayName,
fileName: null,
imageDb: imgString,
text: null);
//Save food image to database
dbHelper.save(food);
//Add food to FoodList
brain.addFoodToList(food);
//call notifylistener from FoodBrain class
brain.setFoodList(brain.getFoodList());
print(brain.getDisplayName());
});
}
这是从欢迎屏幕运行保存图像的代码:
//Value passed from userInput
_imageFile = imageFile;
await saveImageToDatabase(
_displayName, imageFile);
Navigator.of(context).pop();
食脑类: 使用通知监听器的类
void setFoodList(List<Food> newList) {
_foodList = newList;
notifyListeners();
}
DBHelper类: 初始化并使用各种方法进行数据库连接的类。
class DBHelper {
static Database? _db;
static const String ID = 'id';
//static const String Path = 'path';
static const String Name = 'displayName';
static const String TABLE = 'photosTable';
static const String ImageDb = 'imageDb';
static const String DB_NAME = 'photos.db';
Future<Database> get db async {
if (_db != null) {
return _db!;
}
_db = await initDB();
return _db!;
}
initDB() async {
io.Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, DB_NAME);
var db = await openDatabase(path, version: 1, onCreate: _onCreate);
return db;
}
_onCreate(Database db, int version) async {
await db.execute(
'CREATE TABLE $TABLE ($ID INTEGER, $Name TEXT, $ImageDb TEXT)');
}
Future<Food> save(Food food) async {
var dbClient = await db;
food.id = await dbClient.insert(TABLE, food.toMap());
return food;
}
//Get all photos from db
Future<List<Food>> getPhotos() async {
var dbClient = await db;
List<Map> maps = await dbClient.query(TABLE, columns: [ID, Name, ImageDb]);
List<Food> photos = [];
if (maps.length > 0) {
for (int i = 0; i < maps.length; i++) {
photos.add(Food.fromMap(maps[i]));
}
}
return photos;
}
Future close() async {
var dbClient = await db;
dbClient.close();
}
}
ImageCircle类:
这个类正在显示图像。来自数据库或本地存储。
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(10.0),
child: Material(
elevation: 10.0,
shape: CircleBorder(),
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
//Here we check if its a String or database file image and convert to image
child: Ink.image(
image: widget.image is String
? Image.asset(widget.image).image
: Utility.imageFromBase64String(widget.image).image,
fit: BoxFit.cover,
width: 90.0,
height: 90.0,
child: InkWell(
onTap: () {
setState(() {
getImageToMapList(widget.image, widget.displayName);
//Hide current snackbar on Click if exists. Maybe we need an if exists also?
ScaffoldMessenger.of(context).hideCurrentSnackBar();
getSnackBar();
});
},
//check on lesson about value and how to use it (animations?)
//Hmm hover does not exist on a phone? only when you have a mouse?
),
),
),
);
}
}
附言。我现在已经编辑了更多的课程。
通常它应该工作, 需要知道这堂课发生了什么
//Save food image to database
dbHelper.save(food);
//Add food to FoodList
brain.addFoodToList(food);
//call notifylistener from FoodBrain class
brain.setFoodList(brain.getFoodList());