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

问题描述

我到处都在搜索这个问题。也许我没有使用正确的搜索词。如果已经有人问过了,我深表歉意。如果发现重复,我会迅速删除

我是一位经验不足的编码员,因此这段代码绝对不是最好的代码。希望它是可以理解的。

问题:

  • 我有一个自定义ListTiles列表,其数据通过sqflite软件包保留。
  • 您对它所做的一切(更改信息)已被保留
  • 问题是,我已经实现了reorderables 0.3.2包,以便可以通过拖放对列表进行重新排序
  • 如何使订单更改适用于数据库?如何更改数据库中条形图块的顺序?
  • 现在,它的工作方式是,添加一个栏并将其转到数据库。这就是永远不变的顺序。
  • 如何将从拖放条到其他位置/索引的索引更改应用于我的sqflite数据库

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

Image of the list ordered by DB

Image of altered list order. If you restart app it goes back to image 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();
}

数据库创建代码

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

(插入和删除代码是标准代码) 我猜想要添加的唯一其他相关的数据库代码就是我的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. 将第一个元素从开始位置移动到最后位置。执行此操作后,列表将变为-> [1,3,0]。由此可见,当元素从较小的位置值移动到较大的位置值(0-> 4)时,两个位置之间的所有元素的位置值都必须为-1。因此,位置1变为0,位置2变为1,依此类推。

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


来介绍问题的SQL部分。您的表中可以有一个indexlist_postion列,它对应于元素的位置。重新排序操作发生时,您可以使用index列更新数据库中的元素。

根据任务的索引值以升序从表中使用按顺序操作来读取任务流。

SELECT * FROM tasks_table ORDER BY list_index ASC

希望这会有所帮助,并且我不确定此方法的性能是否很大,并且我目前正在寻找其他方法和算法来以更快的方式完成此任务。但是现在,它对我有用。