Iam new to flutter. I want to implement lazy loading feature for my flutter app which uses sqflite database for storing data. In my database have 1000+ rows. I want to load 10 items when app opens.when i reach the 10th data, then load next 10 and so on. How can i implement this feature??
My database helper class
import 'package:employee_list/models/emp.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class DatabaseHelper {
static final _databaseName = "empdb.db";
static final _databaseVersion = 1;
static final table = 'cars_table';
static final colId = 'id';
static final colName = 'name';
static final colAge = 'age';
static final colPath = 'path';
// make this a singleton class
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
// only have a single app-wide reference to the database
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
// lazily instantiate the db the first time it is accessed
_database = await _initDatabase();
return _database;
}
// this opens the database (and creates it if it doesn't exist)
_initDatabase() async {
String path = join(await getDatabasesPath(), _databaseName);
return await openDatabase(path,
version: _databaseVersion,
onCreate: _onCreate);
}
// SQL code to create the database table
Future _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE $table (
$colId INTEGER PRIMARY KEY AUTOINCREMENT,
$colName TEXT NOT NULL,
$colAge TEXT NOT NULL,
$colPath TEXT NOT NULL
)
''');
}
// Helper methods
// Inserts a row in the database where each key in the Map is a column name
// and the value is the column value. The return value is the id of the
// inserted row.
Future<int> insertEmp(Emp emp) async {
Database db = await instance.database;
return await db.insert(table, {'name': emp.name, 'age': emp.age, 'path': emp.path});
}
// All of the rows are returned as a list of maps, where each map is
// a key-value list of columns.
Future<List<Map<String, dynamic>>> queryAllRows() async {
Database db = await instance.database;
return await db.query(table);
}
// Queries rows based on the argument received
Future<List<Map<String, dynamic>>> queryRows(name) async {
Database db = await instance.database;
return await db.query(table, where: "$colName LIKE '%$name%'");
}
// All of the methods (insert, query, update, delete) can also be done using
// raw SQL commands. This method uses a raw query to give the row count.
Future<int> queryRowCount() async {
Database db = await instance.database;
return Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM $table'));
}
// We are assuming here that the id column in the map is set. The other
// column values will be used to update the row.
Future<int> updateEmp(Emp emp) async {
Database db = await instance.database;
int id = emp.toMap()['id'];
return await db.update(table, emp.toMap(), where: '$colId = ?', whereArgs: [id]);
}
// Deletes the row specified by the id. The number of affected rows is
// returned. This should be 1 as long as the row exists.
Future<int> deleteEmp(int id) async {
Database db = await instance.database;
return await db.delete('DELETE FROM $table');
}
}
my home page
import 'package:employee_list/helper/database_helper.dart';
import 'package:employee_list/second_screen.dart';
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:io' as Io;
import 'dart:convert';
import 'models/emp.dart';
class firstScreen extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return _firstScreen();
}
}
class _firstScreen extends State<firstScreen>{
final dbHelper = DatabaseHelper.instance;
List<Emp> empList;
int count = 0;
@override
Widget build(BuildContext context) {
if (empList == null){
empList = List<Emp>();
updateListView();
}
return Scaffold(
appBar: AppBar(
title: Text('Employee List'),
actions: <Widget>[
Container(
padding: EdgeInsets.only(right: 10.0),
child: IconButton(
icon: Icon(Icons.refresh),
onPressed: () async {
updateListView();
},
),
),
]
),
body:getListView(),
floatingActionButton: FloatingActionButton(
tooltip: 'Add New Employee',
child: Icon(Icons.add),
onPressed: () {
debugPrint('add pressed');
Navigator.push(context, MaterialPageRoute(builder:( context){
return secondScreeen();
updateListView();
}));
},
),
);
}
ListView getListView(){
return ListView.builder(
itemCount: empList.length,
itemBuilder: (BuildContext context, int position){
final _byteImage = Base64Decoder().convert(this.empList[position].path);
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.white,
child: new Image.memory(_byteImage,fit: BoxFit.fill,),
//Icon(Icons.account_circle_outlined),
),
title: Text(this.empList[position].name ,),
subtitle: Text(this.empList[position].age,),
),
);
}
);
}
void updateListView() async{
final allRows = await dbHelper.queryAllRows();
empList.clear();
allRows.forEach((row) => empList.add(Emp.fromMap(row)));
//_showMessageInScaffold('Query done.');
setState(() {});
}
}
You should define limit
(10 entities in your case) and offset
(current page * limit) to query
method:
return database.query(
table,
limit: limit,
offset: page * limit
);
Also, store current page and increase it when new data was loaded. You can find full sample in this project in historyThreads
method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.