List 颤振-如何存储字符串列表:(GetStorage或共享首选项)。使用android

List 颤振-如何存储字符串列表:(GetStorage或共享首选项)。使用android,list,flutter,dart,sharedpreferences,storage,List,Flutter,Dart,Sharedpreferences,Storage,因此,我发现了一个使用Get_存储解决此问题的方法,这要归功于对该主题的一些精彩解释。我设法使用getx和Provider包在添加新内容时保存数据,并在启动应用程序时读取数据(这就是我在这里要讨论的行为)。尽管如此,我还是很难从内存中删除数据 上下文 该项目是一个待办事项列表应用程序,前端工作正常,但在存储方面会变得更加复杂。问题是,我对颤振和移动开发非常陌生,我得到了一些帮助,但这种东西在我的大脑中仍然模糊,我无法使用相同的逻辑删除数据。当我调用box.Remove('key')时,正如文档所

因此,我发现了一个使用Get_存储解决此问题的方法,这要归功于对该主题的一些精彩解释。我设法使用getx和Provider包在添加新内容时保存数据,并在启动应用程序时读取数据(这就是我在这里要讨论的行为)。尽管如此,我还是很难从内存中删除数据

上下文
该项目是一个待办事项列表应用程序,前端工作正常,但在存储方面会变得更加复杂。问题是,我对颤振和移动开发非常陌生,我得到了一些帮助,但这种东西在我的大脑中仍然模糊,我无法使用相同的逻辑删除数据。当我调用box.Remove('key')时,正如文档所说,我的整个列表都被删除了。我一点也不知道为什么会这样

因此,我想知道通过阅读更多的解释,我是否能够更好地理解它。我知道共享首选项在这种情况下非常有用,但我也可以使用get_存储解决方案,因为我更熟悉它

代码:\

在提供者的帮助下,我在另一个文件的listView中调用这些列表--

List<Task> _tasks = [
Task(
  name: "Title",
  description: "Description",
),
以下是从ListView中删除任务的步骤--

void add(String newTitle, newDesc) {
    final task = Task(name: newTitle, description: newDesc);
    _tasks.add(task);

    notifyListeners();
  }
void removeTasks(Task task) {
_tasks.remove(task);

notifyListeners();
}

我试着实现一个逻辑来写和读数据,它成功了。但我也尝试使用这个removeTasks方法通过调用box.remove('tasks');(“任务”是传递给写作和阅读方法的关键)。自从我的listview变空后,它从内存中删除了所有内容

由于我没有那么丰富的经验,我浏览了文档,可以理解一些SharedReferences解释(与got_storage相同),但我在尝试将其应用于代码时遇到了困难

如果您能使用get_存储或共享首选项帮助解决此问题,我将不胜感激

我称之为删除:

// bool variables that control the state of the screen
// since i can change it to show done tasks or on goind tasks
// dont mind that, i think its irrelevant to the problem.
// 
bool isActiveDoing = true;
bool isActiveDone = false;

List finalArray = [];  //it will store the tasks

class TaskList extends StatefulWidget {
  @override
  _TaskListState createState() => _TaskListState();
}

class _TaskListState extends State<TaskList> {
  @override
  Widget build(BuildContext context) {
     //dont mind the if else as well, its not part of the problem 
     //just using it to handle the state of the screen
    if (isActiveDoing) {
      finalArray = Provider.of<TasksFunctions>(context).tasks;
    }
    //TasksFunctions is a class with methods on regards to the storage
    //it contains add tasks, remove, etc... i'm using provider to
    //link those to the screens with the notifyListeners
    if (isActiveDone) {
      finalArray = Provider.of<TasksFunctions>(context).doneTasks;
    }

    //now here is where i call the class tha has the deletion method
    return Consumer<TasksFunctions>(
      builder: (context, tasksFunctions, child) {
        return ListView.builder(
          //list view tha has all the tasks
          itemCount: finalArray.length,
          itemBuilder: (context, index) {
            final task = finalArray[index];

 //using the slidableWidget to wrap the deletion method 
            return SlidableWidget(
              onDismissed: (action) {
                if (isActiveDoing) {
                  Provider.of<TasksFunctions>(context, listen: false)
                      .removeTask(task);
//so here is where i'm deleting those tasks, calling that method
//listed up on this post
               
                }
                if (isActiveDone {
                  Provider.of<TasksFunctions>(context, listen: false)
                      .removeDone(task);
                }
              },
             
            );
          },
        );
      },
    );
  }
}
//控制屏幕状态的布尔变量
//因为我可以将其更改为显示已完成的任务或正在进行的任务
//别介意,我认为这与问题无关。
// 
bool isactivating=true;
bool isActiveDone=false;
列出finalArray=[]//它将存储任务
类TaskList扩展StatefulWidget{
@凌驾
_TaskListState createState()=>\u TaskListState();
}
类_TaskListState扩展状态{
@凌驾
小部件构建(构建上下文){
//如果还有其他问题,也不要介意,这不是问题的一部分
//只是用它来处理屏幕的状态
如果(正在激活){
finalArray=Provider.of(context.tasks);
}
//TasksFunctions是一个类,在存储上具有方法
//它包含添加任务、删除等…我正在使用提供程序
//将这些链接到带有notifyListeners的屏幕
if(isActiveDone){
finalArray=Provider.of(context).doneTasks;
}
//这里是我调用具有删除方法的类的地方
退货消费者(
生成器:(上下文、任务函数、子级){
返回ListView.builder(
//列表视图包含所有任务
itemCount:finalArray.length,
itemBuilder:(上下文,索引){
最终任务=finalArray[索引];
//使用SlideableWidget包装删除方法
返回可滑动小部件(
onDismissed:(行动){
如果(正在激活){
Provider.of(上下文,侦听:false)
.removeTask(任务);
//这里是我删除这些任务的地方,调用那个方法
//列在这篇文章上
}
如果(i)激活{
Provider.of(上下文,侦听:false)
.removeDone(任务);
}
},
);
},
);
},
);
}
}
所以我花了一些时间翻译代码,但我认为它不符合任何颤振的良好实践原则


我还尝试调用storageList.remove(task);然后用box.write('tasks',storageList)重写它;但是没有从内存中删除任何内容(我想可能是因为我没有在整个storageList中循环搜索正确的索引)

听起来你的代码是基于

如果是这种情况,则键
tasks
是整个映射列表的键,而不是单个映射或
Task
。因此,当它清除所有任务时,它的行为与预期一样

为了保留任何更改,您必须从
storageList
中删除该特定映射(任务),然后用
box再次覆盖该框。write('tasks',storageList);
它将保存在相同的映射列表上,并保留您所做的任何删除

如果你在试图删除任务的地方分享你的代码,我可以给你一个更具体的例子

编辑:在评论中回答问题

如果你想走
UniqueKey
路线,你根本不需要索引。你可以这样做

class Task {
  final String name;
  final String description;
  final String key; // not an actual Key but will take the String value of a UniqueKey

  Task({this.key, this.name, this.description});
}
final task = Task(
    description: 'test description',
    name: 'test name',
    key: UniqueKey().toString());
当您添加一个新的
任务时
如下所示

class Task {
  final String name;
  final String description;
  final String key; // not an actual Key but will take the String value of a UniqueKey

  Task({this.key, this.name, this.description});
}
final task = Task(
    description: 'test description',
    name: 'test name',
    key: UniqueKey().toString());
然后,您可以使用地图的
Map
,而不是地图列表,并使用这两个键

  Map storageList = {};

   void addAndStoreTask(Task task) {
    _tasks.add(task);

    final Map storageMap = {}; // temporary map that gets added to storage

    storageMap['name'] = task.name;
    storageMap['description'] = task.description;
    storageMap['key'] = task.key;

    storageList[task.key] = storageMap; // adding temp map to storageList
    box.write('tasks', storageList); // adding map of maps to storage
  }

然后,您的恢复功能将如下所示:

 void restoreTasks() {
    storageList = box.read('tasks'); // initializing list from storage

    storageList.forEach((key, value) { // value here is each individual map that was stored
      final task =
          Task(name: value['name'], description: value['description'], key: key);
      _tasks.add(task);
    });
  }

然后,当您转到“删除”时,您将遍历列表并找到匹配的键。

我想我理解了您的解释,我通过应用您所说的内容成功地删除了任务,我认为在这里最困难的是如何处理u显示的逻辑上的索引,因为当我从storageList中删除元素时,剩余的任务索引不会递减,这与_tasks列表不同,它会在删除某些内容时递减索引,因此当我尝试读取任务时