Search code examples
fluttersqflite

Flutter create listview with local sqlite file


Create a listview from a local sql file(chinook.db) using sqflite Initial issue solved: I/flutter ( 5084): Instance of 'Future' Reference code: https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md Thanks @aakash for the help

main.dart
body: Container(
        child: FutureBuilder(
          future: getSQL("albums"),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            print(snapshot.data);
            if (snapshot.data == null) {
              return Container(child: Center(child: Text("Loading...")));
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    title: Text(snapshot.data[index].title),
                  );
                },
              );
            }
          },
        ),
      ),

getSQL.dart 
Future getSQL(String tableName) async {
  var databasesPath = await getDatabasesPath();
  var path = join(databasesPath, "chinook.db");
// Check if the database exists
  var exists = await databaseExists(path);
  if (!exists) {
    // Should happen only the first time you launch your application
    print("Creating new copy from asset");
    // Make sure the parent directory exists
    try {
      await Directory(dirname(path)).create(recursive: true);
    } catch (_) {}
    // Copy from asset
    ByteData data = await rootBundle.load(join("assets", "chinook.db"));
    List<int> bytes =
        data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
    // Write and flush the bytes written
    await File(path).writeAsBytes(bytes, flush: true);
  } else {
    print("Opening existing database");
  }
// open the database
  var db = await openDatabase(path, readOnly: true);

  List<Map> list = await db.rawQuery('SELECT * FROM $tableName');
  List theList = [];
  for (var n in list) {
    theList.add(MyCategoryFinal(n["Title"]));
  }
  return (theList);
}
class MyCategoryFinal {
  final String title;
  MyCategoryFinal(this.title);
}

Solution

  • I solved this by creating a class for the sqflite table, run a loop on that map list & convert those map items to object list.

    Example code;

    List<ItemBean> items = new List();
        list.forEach((result) {
          ItemBean story = ItemBean.fromJson(result);
          items.add(story);
        });
    

    To create the object you can use https://app.quicktype.io/. Here you can pass the json to generate the class for it.

    After that you can use FutureBuilder to create your listview like this

           FutureBuilder(
              future: MyService.getAllItems(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(child: CircularProgressIndicator());
                }
    
                return ListView.builder(
                  controller: listScrollController,
                  itemCount: snapshot.data.length,
                  reverse: true,
                  itemBuilder: (context, index) {
                    return Text(snapshot.data[index].itemName);
                  },
                );
              },
            ),