【问题标题】:Trying to insert data as a BLOB, getting Argument Error尝试将数据作为 BLOB 插入,出现参数错误
【发布时间】:2020-01-23 15:49:27
【问题描述】:

在我的 Flutter 项目中,我有一个类别,其中包含一个字符串、图标、图标数据和两种颜色: (我不想存储图标,因为我可以用我的 iconData 重新创建它)

class Category {
  Icon icon;
  IconData iconData;
  Color color;
  Color backgroundcolor;
  String name;

[...]

Map<String, dynamic> toMap() {
    return {
      'iconData': iconData,
      'color': color,
      'backgroundcolor': backgroundcolor,
      'name': name
    };
  }

对于我的项目,我导入了 sqflite 数据库,创建了一个表类别(使用“CREATE TABLE 类别(名称文本,iconData BLOB,颜色 BLOB,背景颜色 BLOB”)),现在想将一个类别插入到我的数据库中,如下所示:

Future<void> insertCategory(Category category) async {
  // get reference to the database
  final Database db = await database;

  // insert new category
  await db.insert('categories', category.toMap(),
      conflictAlgorithm: ConflictAlgorithm.replace);

  print("Category inserted.");
}

但是当我尝试插入一个类别时,我得到一个参数错误(无效参数:'IconData' 的实例),我无法弄清楚问题所在。

【问题讨论】:

  • Blob 是原始数据 - 字节数组(很可能)。在这里,我看不到 IconData 到字节数组的转换。所以你可以扩展你的toMap 来这样做。其他解决方案是只存储codePoint(可能是fontFamily),因为这就是你所需要的,并在需要时从codePoint和fontFamily中构造IconData。

标签: flutter sqflite


【解决方案1】:

我的解决方法如下:

创建数据库

CREATE TABLE categories( iconData INTEGER, backgroundcolor INTEGER, name TEXT PRIMARY KEY)

我的 toMap()

Map<String, dynamic> toMap() {
// Color is stored in a 32-bit integer with alpha, red, green, blue -> ARGB
int bc = backgroundcolor.alpha << 8;
bc = bc + backgroundcolor.red << 8;
bc = bc + backgroundcolor.green << 8;
bc = bc + backgroundcolor.blue;
return {
  'iconData': iconData.codePoint,
  'backgroundcolor': bc,
  'name': name
};

我阅读我的类别

Future<List<Category>> getCategoriesFromDatabase() async {
  // get reference to database
  final Database db = await database;

  // Query the table for all categories
  final List<Map<String, dynamic>> maps = await db.query('categories');

  print("Categories read.");
  // Convert the List<Map<String, dynamic> into a List<Category>
  return List.generate(maps.length, (i) {
    // Construct backgroundcolor
    Color bc = Color(maps[i]['backgroundcolor']);
    // Construct iconData
    IconData id =
        IconData(maps[i]['iconData'], fontFamily: Icons.ac_unit.fontFamily);
    return Category(
      name: maps[i]['name'],
      iconData: id,
      backgroundcolor: bc,
    );
  });
}

此解决方法应该适用于大多数数据类型。例如,我使用相同的解决方案来存储日期。我保存了一年、一个月、一天……当从数据库中读取数据时,我构造了一个飞镖日期。

【讨论】:

    【解决方案2】:

    您可以使用字符串类型保存图标数据
    并且您需要从字符串映射到您的图标 Icons 或 FontAwesomeIcons 或 ...

    Map<String, IconData> iconMapping = {
      'facebook' : FontAwesomeIcons.facebook,
      'twitter' : FontAwesomeIcons.twitter,
      'home' : FontAwesomeIcons.home,
      'audiotrack' : Icons.audiotrack,
    };
    
    @override
    Widget build(BuildContext context) {
      return Icon(iconMapping [icon], color: HexColor(color));
    }
    

    类似问答
    Trying to dynamically set the Icon based on a JSON string value
    Flutter: Show different icons based on value

    【讨论】:

    • 我使用了 Chenna Reddy 建议的解决方法。我存储原始数据类型的值,当从数据库中读取我的数据时,我将重新创建我的对象。如果是图标,我会存储代码点和字体系列,并根据此信息创建一个新的 IconData 对象。
    猜你喜欢
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多