首页 > 解决方案 > Flutter - SharedPreferences 保存列表

问题描述

我有一个连接到 Firebase 的应用程序,我正在制作一个屏幕来显示所有发送的通知,因为我正在使用 SharedPreferences。但是当通知到达地图时,我将它放在列表 <Map <dynamic, dynamic >> 中,以显示通知。

      String title, body;
      Map<dynamic, dynamic> notific;
      List<Map<dynamic, dynamic>> notifList = [];
///Widget
    return Scaffold(
          extendBody: true,
          backgroundColor: widget._colors.white,
          appBar: appBar,
          body: ListView.builder(
            itemCount: notifList.length,
            itemBuilder: (context, i) {
              return Card(
                margin: EdgeInsets.all(10),
                elevation: 4,
                child: ListTile(
                  title: Text(
                    notifList.elementAt(i)['title'],
                  ),
                  subtitle: Text(
                    notifList.elementAt(i)['body'],
                  ),
                ),
              );
            },
          ),
        );
      }

Firebase 方法

  Future<dynamic> fcmMessageReceiver() async {
    FirebaseMessaging.instance.getInitialMessage().then((value) {
      if (value != null) {}
    });

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      if (message.notification != null) {
        notific = {
          'title': message.notification.title,
          'body': message.notification.body
        };
        notifList.add(notific);
        setState(() {
          title = message.notification.title;
          body = message.notification.body;
        });
        print('MENSAGEM: $notific');
      }
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {});
  }

Shared Preferences 方法,在 initState() 上调用

  void savePush() async {
    SharedPreferences sharePref = await SharedPreferences.getInstance();
    final strList = sharePref.getStringList('push')??[];
    sharePref.setStringList('push', notifList.toString());
  }

我的问题是,我怎样才能保留这些通知,以便每当我想看到它们时,我都可以轻松获取它们,并使用通知设置卡片?

标签: firebaseflutterdart

解决方案


所以,有很多方法可以解决这个问题,我的一些方法是将每条消息转换为 aJSON encoded string然后将其推送到sharedPreference.setStringList(list). 另一种方法是制作整个列表 a并通过调用JSON encoded string将其保存为喜欢的字符串。SharedPreferencessharedPreference.setString(list)


假设您的消息列表是这样的:

List<Map<String, dynamic>> messagesForUI = [];

而且,您已经初始化SharedPreferences和以前的消息SharedPreferences是这样的:

SharedPreferences sharedPreference = await SharedPreferences.getInstance();
List<String> sharedPreferenceMessages = [];

现在,要从中检索所有以前的消息SharedPreferences,然后将以前的消息设置到方法messagesForUI内部initState,您可以执行以下操作:

sharedPreferenceMessages = sharedPreference.getStringList("messages") ?? [];
sharedPreferenceMessages.forEach((element) {
  Map<String, dynamic> messageMap = Map<String, dynamic>.from(json.decode(element));
  messagesForUI.add(messageMap);
});

现在,您的清单已准备就绪。

假设您有一条来自 FCM 的新消息,并且您想将其保存到SharedPreferences. 让我们以这种方式保存新消息:

Map<String, dynamic> newMessage = Map<String, dynamic>.from(fcmMessage);

setState((){
  messagesForUI.add(newMessage);
});

String newMessageJson = json.encode(newMessage);
sharedPreferenceMessages.add(newMessageJson);
sharedPreference.setStringList("messages", sharedPreferenceMessages);

你去吧。您也可以SharedPreferences通过调用将消息保存到sharedPreference.setString(map),就像这种方法一样。如果需要演示该过程,请在此处发表评论。

示例代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class NotificationRoute extends StatefulWidget {
  @override
  _NotificationRouteState createState() => _NotificationRouteState();
}

class _NotificationRouteState extends State<NotificationRoute> {
  List<Map<String, dynamic>> messagesForUI = [];
  List<String> sharedPreferenceMessages = [];
  SharedPreferences sharedPreference;

  @override
  void initState() {
    init();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: messagesForUI.isEmpty
          ? Center(
              child: Text("No notifications"),
            )
          : ListView.builder(
              itemBuilder: (context, index) {
                final Map<String, dynamic> message = messagesForUI[index];
                return ListTile(
                  title: Text(message["title"]),
                  subtitle: Text(message["body"]),
                );
              },
              shrinkWrap: true,
              physics: ScrollPhysics(),
              scrollDirection: Axis.vertical,
              itemCount: messagesForUI.length,
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Map<String, dynamic> newMessage = {"title": "test title", "body": "test body"};

          setState(() {
            messagesForUI.add(newMessage);
          });

          String newMessageJson = json.encode(newMessage);
          sharedPreferenceMessages.add(newMessageJson);
          sharedPreference.setStringList("messages", sharedPreferenceMessages);
        },
        child: Icon(Icons.add),
      ),
    );
  }

  init() async {
    sharedPreference = await SharedPreferences.getInstance();
    sharedPreferenceMessages = sharedPreference.getStringList("messages") ?? [];
    sharedPreferenceMessages.forEach((element) {
      Map<String, dynamic> messageMap = Map<String, dynamic>.from(json.decode(element));
      messagesForUI.add(messageMap);
    });
  }
}


现在,由于我的项目没有任何FCM设置,我只是将消息添加过程复制到SharedPreferencevia FloatingActionButton

快乐编码:D


推荐阅读