Как реализовать ленивую загрузку из sqflite во флаттере

Я новичок в трепете. Я хочу реализовать функцию отложенной загрузки для моего приложения flutter, которое использует базу данных sqflite для хранения данных. В моей базе данных более 1000 строк. Я хочу загрузить 10 элементов при открытии приложения. Когда я достигаю 10-го числа, затем загружаю следующие 10 и так далее. Как я могу реализовать эту функцию?

Мой вспомогательный класс базы данных

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');
  }
}

моя домашняя страница

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(() {});
    }

}

person Natsu Dragnal    schedule 03.02.2021    source источник
comment
Я ищу такое же решение.   -  person Vimal Mistry    schedule 05.02.2021


Ответы (1)


Вы должны определить limit (10 объектов в вашем случае) и offset (ограничение текущей страницы *) для метода query:

return database.query(
  table,
  limit: limit,
  offset: page * limit
);

Также сохраните текущую страницу и увеличивайте ее при загрузке новых данных. Вы можете найти полный образец в этом проекте. в historyThreads методе.

person fartem    schedule 03.02.2021
comment
у вас есть какой-нибудь пример или ссылка на учебник? - person Natsu Dragnal; 03.02.2021
comment
у меня обновленный вопрос. можешь помочь мне? - person Natsu Dragnal; 05.02.2021
comment
Что вы добавили к вопросу? - person fartem; 05.02.2021
comment
мой вспомогательный класс базы данных и домашняя страница, которая отображает список - person Natsu Dragnal; 05.02.2021
comment
Вы можете реализовать query реализацию метода из ответа. - person fartem; 05.02.2021