Flutter/Dart:检索 sqflite 数据并放入 array/list
Flutter/Dart: Retrieve sqflite data and put into an array/list
我将练习作为字符串存储在我的 sqflite 数据库中。我想检索数据并将其放入名为 typeArray[] 的列表或数组中。我正在尝试检索 class 中的数据,该数据将使用函数中的练习列表来执行随机锻炼生成。因此我需要在进行计算之前检索列表。然后使用 MaterialPageRoute() 将这些锻炼生成器函数的 return 值传递给 custom_workout_screen.dart,我在其中使用函数的 return 值在屏幕上显示为字符串。
我让它与预定义列表一起工作,即我设置列表的地方 = ['exerciseOne'、'exerciseTwo'、'etc']
我如何将数据拉入非无状态或有状态的 class 中?我很乐意做这项工作,但对解决问题的方法感到困惑 - 感谢任何指导!
生成要传递到自定义锻炼屏幕的自定义锻炼: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;
}
数据库助手: 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,
style: kTitleStyleDark,
),
),
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!', style: kCommentTextStyle),
Text(
customWorkout2,
style: kMainTextStyledDark,
),
Text('REST 30s!', style: kCommentTextStyle),
Text(
customWorkout3,
style: kMainTextStyledDark,
),
Text('REST 30s!', style: kCommentTextStyle),
Text(
customWorkout4,
style: kMainTextStyledDark,
),
Text('REST 30s!', style: kCommentTextStyle),
Text(
customWorkout5,
style: kMainTextStyledDark,
),
Text('GOOD JOB, REST!', style: kCommentTextStyle),
Text('OR GO AGAIN?', style: kCommentTextStyle),
],
),
),
SizedBox(
height: 50.0,
),
BottomButton(
buttonTitle: 'NEW WORKOUT',
onTap: () {
Navigator.pop(context);
},
),
],
),
),
);
}
}
基本上有两种方法可以解决您的问题[据我所知,可能更多]。第一种方法是使用 Provider package。下面我将详细解释该方法:
第一种方法
假设您已经有了 DatabaseHelper
文件,您可以为随机选择的锻炼定义 class [类似这样,但不一定是这样]。为了简化和关注一个概念,我假设数据库具有以下字段: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
文件中,您需要使用您选择的 Provider 小部件 (MultiProvider/Provider) 包装您的 MaterialApp
小部件。
最后,在您计划填充数据的文件中,您可以使用 FutureBuilder
从数据库中异步获取数据,未来为 Provider.of<TaskProvider>(context, listen: false).fetchAndSetWorkouts()
并使用 Consumer
的构建器来从 workout_provider.dart
.
检索项目 getter
这可能有很多需要掌握的地方,所以我建议您访问 Provider 包的文档页面以及 GitHub 上的示例,有很多人比我解释得更好
第二种方法
这是一种更简单的方法,但灵活性和效率较低。您只需在需要数据的地方直接异步使用 DatabaseHelper
如下:
Future<List<RandomWorkout>> 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();
return workouts;
}
我将练习作为字符串存储在我的 sqflite 数据库中。我想检索数据并将其放入名为 typeArray[] 的列表或数组中。我正在尝试检索 class 中的数据,该数据将使用函数中的练习列表来执行随机锻炼生成。因此我需要在进行计算之前检索列表。然后使用 MaterialPageRoute() 将这些锻炼生成器函数的 return 值传递给 custom_workout_screen.dart,我在其中使用函数的 return 值在屏幕上显示为字符串。
我让它与预定义列表一起工作,即我设置列表的地方 = ['exerciseOne'、'exerciseTwo'、'etc']
我如何将数据拉入非无状态或有状态的 class 中?我很乐意做这项工作,但对解决问题的方法感到困惑 - 感谢任何指导!
生成要传递到自定义锻炼屏幕的自定义锻炼: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;
}
数据库助手: 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,
style: kTitleStyleDark,
),
),
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!', style: kCommentTextStyle),
Text(
customWorkout2,
style: kMainTextStyledDark,
),
Text('REST 30s!', style: kCommentTextStyle),
Text(
customWorkout3,
style: kMainTextStyledDark,
),
Text('REST 30s!', style: kCommentTextStyle),
Text(
customWorkout4,
style: kMainTextStyledDark,
),
Text('REST 30s!', style: kCommentTextStyle),
Text(
customWorkout5,
style: kMainTextStyledDark,
),
Text('GOOD JOB, REST!', style: kCommentTextStyle),
Text('OR GO AGAIN?', style: kCommentTextStyle),
],
),
),
SizedBox(
height: 50.0,
),
BottomButton(
buttonTitle: 'NEW WORKOUT',
onTap: () {
Navigator.pop(context);
},
),
],
),
),
);
}
}
基本上有两种方法可以解决您的问题[据我所知,可能更多]。第一种方法是使用 Provider package。下面我将详细解释该方法:
第一种方法
假设您已经有了 DatabaseHelper
文件,您可以为随机选择的锻炼定义 class [类似这样,但不一定是这样]。为了简化和关注一个概念,我假设数据库具有以下字段: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
文件中,您需要使用您选择的 Provider 小部件 (MultiProvider/Provider) 包装您的 MaterialApp
小部件。
最后,在您计划填充数据的文件中,您可以使用 FutureBuilder
从数据库中异步获取数据,未来为 Provider.of<TaskProvider>(context, listen: false).fetchAndSetWorkouts()
并使用 Consumer
的构建器来从 workout_provider.dart
.
这可能有很多需要掌握的地方,所以我建议您访问 Provider 包的文档页面以及 GitHub 上的示例,有很多人比我解释得更好
第二种方法
这是一种更简单的方法,但灵活性和效率较低。您只需在需要数据的地方直接异步使用 DatabaseHelper
如下:
Future<List<RandomWorkout>> 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();
return workouts;
}