首页 > 解决方案 > 假设一个列表被分配了一个 SQLite 数据库的查询,如何确保该列表不为空?扑

问题描述

我正在使用 sqflite 包制作一个带有 SQLite 数据库的 Flutter 应用程序。我有一个带有必要方法的数据库助手类。在其中一个页面中,我想将数据显示为卡片列表。我也有一个图像存储到数据库中,因此在同一页面中我必须将图像转换回文件。在那个名为 DataPage 的页面类中,我创建了一个名为 query 的方法,它调用数据库的 query 方法并将该值分配给一个名为 listLokasi 的列表。我还创建了一个名为 convert 的方法,它调用 List.generate,其中一个参数是 listLokasi.length。同时,我将这 2 个方法放在 _DataPageState 的构造函数中,因为 DataPage 是一个有状态的小部件。问题是当我运行应用程序时,当我尝试在 null 上调用 length 时显示一个错误,显示 NoSuchMethodError,这意味着 listLokasi 为空。所以我在查询方法中,在查询方法之后的构造函数中,在转换方法中都放置了断言。结果是查询方法中的断言没有触发,而构造函数中的断言立即触发。我检查了我的数据库助手类并查看了我的代码,但我找不到我的代码中的缺陷。对此问题的任何帮助将不胜感激。我将在下面显示代码。

这是数据库助手类。

class DatabaseHelper {
  static final _instance = DatabaseHelper._internal();

  DatabaseHelper._internal();

  factory DatabaseHelper() {
    return _instance;
  }

  Database db;

  Future initDatabase() async {
    var databasePath = await getDatabasesPath();
    var path = join(databasePath, 'table.db');
    db = await openDatabase(path, version: 1, onCreate: onCreate);
  }

  onCreate(Database db, int version) async {
    await db.execute('''
    CREATE TABLE lokasi 
    (id INTEGER PRIMARY KEY, 
    name TEXT, 
    description TEXT, 
    category TEXT, 
    latitude REAL, 
    longitude REAL, 
    image BLOB)
    ''');
  }

  Future<Lokasi> insert(Lokasi lokasi) async {
    await db.insert('lokasi', lokasi.toJson());
    return lokasi;
  }

  Future<List<Lokasi>> query() async {
    var list = await db.query('lokasi');
    return List.generate(list.length, (i) => Lokasi.fromJson(list[i]));
  }
}

这是 DataPage 类。

class DataPage extends StatefulWidget {
  final savedUsername;
  const DataPage({this.savedUsername = 'User'});

  @override
  _DataPageState createState() => _DataPageState();
}

class _DataPageState extends State<DataPage> {
  DatabaseHelper db = DatabaseHelper();
  List<Lokasi> listLokasi;
  List<LokasiConvert> listLokasiConvert;

  _DataPageState() {
    query();
    assert(listLokasi != null);
    convert();
  }

  convert() {
    assert(listLokasi != null);
    listLokasiConvert = List.generate(
      listLokasi.length,
      (i) => LokasiConvert(
        name: listLokasi[i].name,
        description: listLokasi[i].category,
        category: listLokasi[i].category,
        latitude: listLokasi[i].latitude,
        longitude: listLokasi[i].longitude,
        image: File.fromRawPath(listLokasi[i].image),
      ),
    );
  }

  Future<List<Lokasi>> query() async {
    listLokasi = await db.query();
    assert(listLokasi != null);
    return listLokasi;
  }

  void sendUsername(BuildContext context) {
    String username = widget.savedUsername;
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => MainPage(username: username),
      ),
    );
  }

  void sendUsernameToChart(BuildContext context) {
    String chartUsername = widget.savedUsername;
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) => ChartPage(savedUsername: chartUsername),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text('Data'),
        actions: [
          RaisedButton(
            child: Text('Logout'),
            onPressed: () {
              Navigator.popUntil(context, ModalRoute.withName('/'));
            },
          ),
          RaisedButton(
            child: Text('Main'),
            onPressed: () {
              sendUsername(context);
            },
          ),
          RaisedButton(
            child: Text('Charts'),
            onPressed: () {
              sendUsernameToChart(context);
            },
          ),
        ],
      ),
      body: ListView.builder(
        itemBuilder: (context, i) {
          return Card(
              child: Row(
            children: [
              Image.file(
                listLokasiConvert[i].image,
                width: 100,
                height: 100,
              ),
              Column(
                children: [
                  Text(listLokasiConvert[i].name),
                  Text(listLokasiConvert[i].category),
                  Text(listLokasiConvert[i].description),
                  Text('Coordinates: ' +
                      listLokasiConvert[i].latitude.toString() +
                      ', ' +
                      listLokasiConvert[i].longitude.toString()),
                ],
              )
            ],
          ));
        },
        itemCount: listLokasiConvert.length,
      ),
    );
  }
}

再次感谢您提供的任何帮助。

标签: fluttersqlitesqflite

解决方案


也许你可以试试这个。希望对您有所帮助。

db.query().then((value) {
  setState(() {
        listLokasi = value
  });
});

推荐阅读