Cache two Lists in flutter

1,088

I didn't get complete requirement by your question description but you can use shared_preferences library to store the data list as following
Add following line pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  shared_preferences:

You can use this example and add more utility methods as per you requirement.

import 'dart:convert';

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

void main() async {
  AppConfig.init(() {
    runApp(MyApp());
  });
}

class CustomModel {
  int id;
  String name;

  CustomModel({this.id, this.name});

  factory CustomModel.fromJson(Map<String, dynamic> json) {
    return CustomModel(id: json["id"], name: json["name"]);
  }

  Map<String, dynamic> toJson() => {"id": id, "name": name};

  @override
  String toString() {
    return "id: $id, name: $name";
  }
}

class AppConfig {
  static Future init(VoidCallback callback) async {
    WidgetsFlutterBinding.ensureInitialized();
    await SharedPreferenceUtils.init();
    callback();
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class SharedPreferenceUtils {
  static SharedPreferences prefs;

  static init() async {
    prefs = await SharedPreferences.getInstance();
    // storing lists
    await putStringList("m_list", ["abc", "def"]);
    await putObjectList("data",
        [CustomModel(id: 1, name: "Bob"), CustomModel(id: 2, name: "Alice")]);
  }

  static Future<bool> putStringList(String key, List<String> list) async {
    return prefs.setStringList(key, list);
  }

  static List<String> getStringList(String key) {
    return prefs.getStringList(key);
  }

  static Future<bool> putObjectList(String key, List<Object> list) async {
    if (prefs == null) return null;
    List<String> _dataList = list?.map((value) {
      return json.encode(value);
    })?.toList();
    return prefs.setStringList(key, _dataList);
  }

  static List<T> getObjList<T>(String key, T f(Map v),
      {List<T> defValue = const []}) {
    if (prefs == null) return null;
    List<Map> dataList = getObjectList(key);
    List<T> list = dataList?.map((value) {
      return f(value);
    })?.toList();
    return list ?? defValue;
  }

  static List<Map> getObjectList(String key) {
    if (prefs == null) return null;
    List<String> dataList = prefs.getStringList(key);
    return dataList?.map((value) {
      Map _dataMap = json.decode(value);
      return _dataMap;
    })?.toList();
  }
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Text(SharedPreferenceUtils.getStringList("m_list").toString()),
              Text(SharedPreferenceUtils.getObjList<CustomModel>(
                  "data", (v) => CustomModel.fromJson(v)).toString()),
            ],
          ),
        ),
      ),
    );
  }
}

You don't need to store the lists in init() as it's done for this example. You can also pass data from one widget to others in multiple ways and if you are looking for state management then you can use BLOC or providers.

Share:
1,088
Thaanu
Author by

Thaanu

Updated on December 20, 2022

Comments

  • Thaanu
    Thaanu over 1 year

    I want to cache two lists that got from Firebase to use to later when the user is offline

    This is the full code for my list display screen -

    import 'package:flutter/material.dart';
    
    import 'package:naamaa/calculations/name-list-calc.dart';
    
    List namesList = List();
    List meaningsList = List();
    
    class NameList extends StatefulWidget {
      @override
      _NameListState createState() => _NameListState();
    }
    
    class _NameListState extends State<NameList> {
      Future<String> getPosts() async {
        var names = await NameListCalc().nameListCalc();
        namesList.addAll(names[0]);
        meaningsList.addAll(names[1]);
        String s = 'test';
        return s;
      }
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<String>(
          future: getPosts(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Scaffold(
                resizeToAvoidBottomPadding: false,
                body: ListView.builder(
                  padding: EdgeInsets.zero,
                  itemBuilder: (context, position) {
                    return Row(
                      children: <Widget>[
                        Container(
                          width: 100,
                          child: Text(namesList[position]),
                        ),
                        Container(
                          child: Text(meaningsList[position]),
                        )
                      ],
                    );
                  },
                  itemCount: namesList.length,
                ),
              );
            } else {
              return Text(':(');
            }
          },
        );
      }
    }
    

    I want to cache namesList and meaningsList for later use.

    If someone can help it would be great :)

    • Payam Zahedi
      Payam Zahedi about 4 years
      did you check this plugin?
    • Thaanu
      Thaanu about 4 years
      Yes, but I have no idea how to use that with the list. :(