Flutter:使用共享首选项插件存储保存的收藏列表

Posted

技术标签:

【中文标题】Flutter:使用共享首选项插件存储保存的收藏列表【英文标题】:Flutter: using shared preferences plugin to store saved favorite list 【发布时间】:2020-10-31 13:14:20 【问题描述】:

以下是我的 JSON 文件,其中包含数据:

[
    
        "city": "City1",
        "attractions": [
            "attraction1",
            "attraction2"
        ],
    ,
    
        "city": "city2",
        "attractions": [
            "attraction1",
            "attraction2",
        ],
    ,
]

我的实现代码是一个从 JSON 文件中获取数据的列表视图构建器。该代码还具有将城市保存为收藏夹的选项选项,该选项可以在另一个页面中显示为已保存收藏夹的列表:

class Index extends StatefulWidget 
  @override
  _IndexState createState() => _IndexState();

List data;
List<Cities> citylist = List();
List<Cities> citysavedlist = List();
int index;
class _IndexState extends State<Index> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(),
      body: listView(),
    );
  
  Future<String> fetchData() async 
    String data =
        await DefaultAssetBundle.of(context).loadString("assets/data.json");
    final jsonResult = json.decode(data);
    this.setState(() 
      jsonResult
          .forEach((element) => citylist.add(new Cities.fromJson(element)));
    );
    return "Success!";
  

  @override
  void initState() 
    super.initState();
    fetchData();
  

  listView() 
    return ListView.builder(
      itemCount: citylist == null ? 0 : citylist.length,
      itemBuilder: (context, index) 
        return Column(
          children: <Widget>[_buildRow(index, citylist)],
        );
      ,
    );
  

  Widget _buildRow(index, citylist) 
    final bool alreadySaved = citysavedlist.contains(citylist[index]);
    return Padding(
      padding: const EdgeInsets.only(top: 5.0, left: 5.0, right: 5.0),
      child: Card(
        child: ListTile(
            title:
                Text(citylist[index].title, style: TextStyle(fontSize: 22.0)),
            trailing: IconButton(
              icon: Icon(
                alreadySaved ? Icons.star : Icons.star_border,
                color: alreadySaved ? Colors.blue : Colors.blue,
              ),
              onPressed: () 
                setState(() 
                  if (alreadySaved) 
                    citysavedlist.remove(citylist[index]);
                   else 
                    citysavedlist.add(citylist[index]);
                  
                );
              ,
            ), //subtitle: Text(subtitle),
            onTap: () 
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => Detail(citylist[index])));
            ),
      ),
    );
  


void _pushSaved() 
    Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (BuildContext context) 
          final Iterable<ListTile> tiles = citysavedlist.map(
            (Cities pair) 
              return ListTile(
                  title: Text(
                    pair.city,
                  ),
                  onTap: () 
                    Navigator.push(context,
                        MaterialPageRoute(builder: (context) => Detail(pair)));
                  );
            ,
          );

          final List<Widget> divided = ListTile.divideTiles(
            context: context,
            tiles: tiles,
          ).toList();
          return Scaffold(
            appBar: AppBar(
              title: const Text('Saved Suggestions'),
            ),
            body: ListView(children: divided),
          );
        ,
      ),
    );
  

这是模型类:

List<Cities> citiesFromJson(String str) =>
    List<Cities>.from(json.decode(str).map((x) => Cities.fromJson(x)));
String citiesToJson(List<Cities> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Cities 
  Cities(
    this.city,
    this.attractions,
  );

  String city;
  List<String> attractions;

  factory Cities.fromJson(Map<String, dynamic> json) => Cities(
        city: json["city"],
        attractions: List<String>.from(json["attractions"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => 
        "city": city,
        "attractions": List<dynamic>.from(attractions.map((x) => x)),
      ;

现在遇到一个问题,收藏的城市没有保存,所以当应用关闭再重新打开时,收藏列表会消失,因为它没有保存。

我知道有一个名为Shared preferences 的插件可以实现存储已保存数据的功能,但我无法将此插件集成到我的代码中。有人可以帮忙吗?

【问题讨论】:

【参考方案1】:

首先你要做的是在 pubspec 中获取包

import 'package:shared_preferences/shared_preferences.dart';

SharedPreferences prefs = await SharedPreferences.getInstance();

现在要保存json数据你要做的是

prefs.setString('mydata', json.encode(yourjsondata));

检索此数据 您必须使用您指定的确切名称,在我的情况下为“mydata”

json.decode(preferences.getString('mydata'))

记住如果你想保存这么多数据项,建议使用 sqflite 或 hive,或者如果你仍然想使用 shared_preferences,你可以将计数器保存为

保存

var counter = (prefs.getInt('Counter')??0)+1;
prefs.setString('Counter:$counter', json.encode(yourdata));

按顺序恢复

var listCount = preferences.getInt('Counter');

使用 listCount 循环然后使用

json.decode(preferences.getString('Counter:$variable'))

【讨论】:

非常感谢 Krish 的回答。我是新来的,我真的可以根据你的回答修改我的代码。您能否将您的答案插入我的代码中。将不胜感激。 使用我在函数中提到的相同的东西并更改名称很容易

以上是关于Flutter:使用共享首选项插件存储保存的收藏列表的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 dart/flutter 中的共享首选项保存和获取列表列表

如何在不使用共享首选项的情况下将数据存储为颤动的对象[关闭]

Flutter 存储共享首选项中的自定义类列表

Flutter:删除所有已保存的shared_preferences首选项

Flutter ios 共享首选项显示 setstring on null 错误

如何保存和获取存储在共享首选项中的包名称?