Flutter-sqflite:如何更改持久化数据的顺序(索引)



我到处都在找这个问题。也许我没有使用正确的搜索词。如果已经有人问了,我很抱歉。如果它是重复的,我会很快删除它。

我是一个相当缺乏经验的程序员,所以这个代码肯定不会是最好看的一个。希望这是可以理解的。

问题:

  • 我有一个自定义ListTiles的列表,它的数据通过sqflite包持久化
  • 你对它所做的一切(更改信息(都已被持久化
  • 问题是,我已经实现了可重新排序0.3.2包,这样列表就可以通过拖放进行重新排序
  • 如何将订单更改应用于数据库?如何更改数据库中条形图的顺序
  • 按照它现在的工作方式,你添加一个栏,它就会进入数据库。这是永远不变的秩序
  • 我如何使从拖动条到不同位置的索引更改/索引应用于我的sqflite数据库

我将保留呈现列表的代码、fetchAndSetBars方法以及用于创建和更新DB的DB方法。如果我遗漏了任何人可能需要的信息,请告诉我。我会尽快把它放在这里

DB 排序的列表图像

更改列表顺序的图像。如果你重新启动应用程序,它会返回到图像1

这是问题列表的代码:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:budget_mentor/models/bar_tile_data.dart';
import 'package:reorderables/reorderables.dart';
class BarTilesList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder(
future:
Provider.of<BarTileData>(context, listen: false).fetchAndSetBars(),
builder: (ctx, snapshot) => snapshot.connectionState ==
ConnectionState.waiting
? Center(
child: CircularProgressIndicator(),
)
: Consumer<BarTileData>(
builder: (context, barTileData, child) {
ScrollController _scrollController =
PrimaryScrollController.of(context) ?? ScrollController();
void _onReorder(int oldIndex, int newIndex) {
Widget row = barTileData.barTiles.removeAt(oldIndex);
barTileData.barTiles.insert(newIndex, row);
}
return Column(
children: <Widget>[
Expanded(
child: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
ReorderableSliverList(
delegate: ReorderableSliverChildBuilderDelegate(
(BuildContext context, int index) =>
barTileData.barTiles[index],
childCount: barTileData.barTiles.length),
onReorder: _onReorder,
)
],
),
),
Text('Placeholder'),
],
);
},
),
);
}
}

FetchAndSetBars方法:

Future<void> fetchAndSetBars() async {
final dataList = await DBHelper.getBarTileDBData('user_bars');
barTiles = dataList.map((bar) {
final int colorHex = int.tryParse(bar['barColor']);
final String valueKey = bar['barKey'];
return BarTile(
barTitle: bar['barTitle'],
barColor: Color(colorHex),
barWidth: bar['barWidth'],
id: bar['barID'],
key: ValueKey(valueKey),
);
}).toList();
notifyListeners();
}

DB创建代码:

static Future<Database> barTilesDatabase() async {
final dbPath = await sql.getDatabasesPath();
return sql.openDatabase(path.join(dbPath, 'bars_tile_list.db'),
onCreate: (db, version) {
return db.execute(
'CREATE TABLE user_bars($barTitle TEXT PRIMARY KEY, $barColor TEXT, $barWidth REAL, $barID TEXT, $barKey TEXT)');
}, version: 5);
}

(插入和删除代码为标准代码(我猜唯一要添加的其他相关DB代码将是我的updateDB方法:

static updateUserBarsDB(
String barTitle,
Color barColor,
double barWidth,
String barID,
String barKey) async {
Database db = await DBHelper.barTilesDatabase();
final String colorValueAsString = barColor.value.toString();
Map<String, dynamic> updatedBarTile = {
DBHelper.barTitle: barTitle,
DBHelper.barColor: colorValueAsString,
DBHelper.barWidth: barWidth,
DBHelper.barID: barID,
DBHelper.barKey: barKey,
};
String id = barID;
await db.update('user_bars', updatedBarTile,
where: '${DBHelper.barID} = ?', whereArgs: [id]);
print(await db.query('user_bars'));
}

好吧,我正在尝试在我的应用程序中构建同样的东西,下面是关于如何处理这一问题的建议。我不是一个数据库专家,所以不能真正说这在数据库操作方面是否具有成本效益或优化。

假设您在列表[0, 1, 2, 3]中有以下元素。我选择这些数字是为了表明它们的指数。

现在考虑以下操作。

  1. 将第一个元素从开始移动到最后一个位置。在执行该操作之后,列表将变为该->CCD_ 2。由此,我们可以理解,当一个元素从较小的位置值移动到较大的位置值(0->4(时,那么我们两个位置之间的所有元素都需要在其位置值中获得-1。因此,位置1变为0,2变为1,依此类推。

  2. 将最后一个元素从last移动到起始位置。在执行该操作之后,列表将变为该->[3, 0, 1, 2]。由此,我们可以理解,当一个元素从较大的位置值移动到较小的位置值(3->0(时,我们需要执行与上述操作相反的操作,并且我们将加1加到两个索引之间的所有位置。因此,当第4个元素(3(变为第1个元素(0(时,第4个以上和第1个位置(包括第1个(以下的所有元素都需要将其位置增加1。


问题的SQL部分。表中可以有一个indexlist_postion列,与元素的位置相对应。进行重新排序操作时,可以使用index列更新数据库中的元素。

根据任务的索引值,按升序从表中按顺序读取任务流。就是一个例子

SELECT * FROM tasks_table ORDER BY list_index ASC

希望这能有所帮助,我不确定这种方法在大列表上的性能,我目前正在寻找一些其他方法和算法,以更快的方式做到这一点。但就目前而言,它对我有效。

最新更新