Flutter / Dart:检索sqflite数据并放入数组/列表中

问题描述

我的练习以字符串形式存储在我的sqflite数据库中。我想检索数据并将其放入名为 typeArray [] 的列表或数组中。我正在尝试在一个类中检索数据,该类将使用函数中的练习列表来执行随机锻炼生成。因此,在进行计算之前,我需要检索列表。然后,使用MaterialPageRoute()将这些锻炼生成函数的返回值传递给 custom_workout_screen.dart 在这里我使用函数的返回值以字符串形式显示在屏幕上。

我将其与预定义列表一起使用,即在其中设置列表= ['exerciSEOne','exerciseTwo','etc']

如何在非无状态或全状态的类中提取数据?我很高兴从事这项工作,但在解决问题的方法上感到困惑-任何指导表示赞赏!

生成自定义锻炼并传递到“自定义锻炼”屏幕:generate_custom.dart

class GenerateCustom {
  int rnd;
  // NEED TO SET typeArray to values from SQFLITE DB ?
  List typeArray = [];

  GenerateCustom({this.difficulty});
  final int difficulty;
  String workout;
  String ex1;
  String ex2;
  String ex3;
  String ex4;
  String ex5;
  
  String getStrengthType() {
    var random = Random();
    var i = random.nextInt(14);
    print(typeArray[i]);
    return typeArray[i];
  }
  
  String cuExerciSEOne() {
    if (difficulty == 1) {
      workout = ('1: ' +
          getStrengthType() +
          ' ' +
          getRepsEasy() +
          'x' +
          getSetsEasy());
    } else if (difficulty == 2) {
      workout = ('1: ' +
          getStrengthType() +
          ' ' +
          getRepsMedium() +
          'x' +
          getSetsMedium());
    } else {
      workout = ('1: ' +
          getStrengthType() +
          ' ' +
          getRepsHard() +
          'x' +
          getSetsHard());
    }
    return workout;
  }

DatabaseHelper: database_helper.dart

class DatabaseHelper {
  static DatabaseHelper _databaseHelper;
  static Database _database;
  String exerciseTable = 'exercise_table';
  String colId = 'id';
  String title = 'title';

  DatabaseHelper._createInstance();
  factory DatabaseHelper() {
    if (_databaseHelper == null) {
      _databaseHelper = DatabaseHelper._createInstance();
    }
    return _databaseHelper;
  }

  Future<Database> get database async {
    if (_database == null) {
      _database = await initializeDatabase();
    }
    return _database;
  }

  Future<Database> initializeDatabase() async {
    //get ios + android dir path
    Directory directory = await getApplicationDocumentsDirectory();
    String path = directory.path + 'exercise.db';

    //Open or create db at path
    var exerciseDatabase =
        await openDatabase(path,version: 1,onCreate: _createDb);
    return exerciseDatabase;
  }

  void _createDb(Database db,int newVersion) async {
    await db.execute(
        'CREATE TABLE $exerciseTable ($colId INTEGER PRIMARY KEY,$title TEXT)');
  }

  Future<List<Map<String,dynamic>>> getExerciseMapList() async {
    Database db = await this.database;
    var result = await db.rawQuery('SELECT * FROM $exerciseTable');
    return result;
  }

  //Insert
  Future<int> insertExercise(Exercise exercise) async {
    Database db = await this.database;
    var result = await db.insert(exerciseTable,exercise.toMap());
    return result;
  }

  //Update
  Future<int> updateExercise(Exercise exercise) async {
    var db = await this.database;
    var result = await db.update(exerciseTable,exercise.toMap(),where: '$colId = ?',whereArgs: [exercise.id]);
    debugPrint('update called');
    return result;
  }

  //Delete
  Future<int> deleteExercise(int id) async {
    var db = await this.database;
    int result =
        await db.rawDelete('DELETE FROM $exerciseTable WHERE $colId = $id');
    return result;
  }

  //get no of objects in db
  Future<int> getCount() async {
    Database db = await this.database;
    List<Map<String,dynamic>> x =
        await db.rawQuery('SELECT COUNT (*) from $exerciseTable');
    int result = Sqflite.firstIntValue(x);
    return result;
  }

  //get Map list from db,convert to Exercise List object
  Future<List<Exercise>> getExerciseList() async {
    //get map list and # of entries in db
    var exerciseMapList = await getExerciseMapList();
    int count = exerciseMapList.length;

    List<Exercise> exerciseList = List<Exercise>();
    //Loop to create exercise list from a map list
    for (int i = 0; i < count; i++) {
      exerciseList.add(Exercise.fromMapObject(exerciseMapList[i]));
    }
    return exerciseList;
  }
}

使用输出的屏幕: custom_workout_screen.dart

class CustomWorkoutScreen extends StatelessWidget {
  CustomWorkoutScreen(
      this.customDifficulty,this.customWorkout1,this.customWorkout2,this.customWorkout3,this.customWorkout4,this.customWorkout5);
  final String customDifficulty;
  final String customWorkout1;
  final String customWorkout2;
  final String customWorkout3;
  final String customWorkout4;
  final String customWorkout5;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: kBackgroundColour,appBar: AppBar(
        backgroundColor: kButtonAndBarColour,title: Text('CUSTOM',style: kTitleStyle),),body: Center(
        child: Column(
          children: <Widget>[
            SizedBox(height: 15.0),Expanded(
              child: Text(
                'WORKOUT',style: kTitleStyleDark,Container(
              child: Text(
                'DIFFICULTY: ' + customDifficulty,SizedBox(
              height: 25.0,Container(
              margin: EdgeInsets.only(bottom: 10.0),child: Column(
                children: <Widget>[
                  Text('READY...GO!',style: kCommentTextStyle),Text(
                    customWorkout1,style: kMainTextStyledDark,Text('REST 30s!',Text(
                    customWorkout2,Text(
                    customWorkout3,Text(
                    customWorkout4,Text(
                    customWorkout5,Text('GOOD JOB,REST!',Text('OR GO AGAIN?',],SizedBox(
              height: 50.0,BottomButton(
              buttonTitle: 'NEW WORKOUT',onTap: () {
                Navigator.pop(context);
              },);
  }
}

解决方法

基本上有两种方法可以解决您的问题[据我所知,可能还有更多]。第一种方法是使用Provider package。下面,我将详细说明该方法:

第一种方法

假设您已经拥有Article文件,则可以为您随机选择的锻炼定义一个类(类似这样,但不一定是这种方式)。为了简化和关注概念,我假设数据库具有以下字段:DatabaseHelper

difficulty TEXT PRIMARY KEY,workout1 TEXT,workout2 TEXT,workout3 TEXT,workout4 TEXT,workout5 TEXT

然后,您需要创建import 'package:flutter/foundation.dart'; class RandomWorkout { final String difficulty; final String workout1; final String workout2; final String workout3; final String workout4; final String workout5; RandomWorkout({ @required this.difficulty,@required this.workout1,@required this.workout2,@required this.workout3,@required this.workout4,@required this.workout5,}); } 文件以处理所有与提供程序相关的功能[添加,删除,获取,但请专注于获取和设置]:

workout_provider.dart

在您的class WorkoutProvider with ChangeNotifier { List<RandomWorkout> _workouts = []; List<Task> get items { return [..._tasks]; } Future<void> fetchAndSetWorkouts() async { final dataList = await DBHelper.getExerciseMapList(); _workouts = dataList .map( (item) => RandomWorkout( difficulty: item['difficulty'],workout1: item['workout1'],workout2: item['workout2'],workout3: item['workout3'],workout4: item['workout4'],workout5: item['workout5'],),) .toList(); notifyListeners(); } } 文件中,您需要将main.dart小部件包装为您选择的提供商小部件(MultiProvider / Provider)。

最后,在您计划填充数据的文件中,可以使用MaterialApp从数据库中以未来的FutureBuilder异步地获取数据,并使用Provider.of<TaskProvider>(context,listen: false).fetchAndSetWorkouts()的构建器来检索数据。来自Consumer的项目获取器。

这可能要掌握很多,所以我建议您访问Provider程序包的文档页面以及GitHub上的示例,有很多人可以比我更好地解释

第二种方法

这是一种更简单的方法,但灵活性和效率较低。您只需直接在需要数据的地方异步使用workout_provider.dart即可,如下所示:

DatabaseHelper