如何实现一个使用flutter_secure_storage包[使用提供程序包]

时间:2020-09-03 15:02:50

标签: flutter provider

我是Flutter和Dart的新手。我用提供程序包和Consumer制作了一个简单的Todos应用程序。我正在尝试实现一个使用flutter_secure_storage包读取和写入设备上的列表数据的过程。 但是我不知道如何实现。

复选框小部件需要布尔值,而secure_storage则需要字符串类型。因此,有必要转换两种类型。这也让我有些困惑。

代码在下面。 如果您能给我一些建议,我会很高兴。

main.dart

// Todos app example

import 'package:consumer_samp/list_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: ChangeNotifierProvider<ListModel>(
        create: (context) => ListModel(),
        child: MyHomePage('Todos app example'),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage(this.title);

  final String title;

  final TextEditingController eCtrl = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      decoration: InputDecoration(
                        border: InputBorder.none,
                        hintText: 'Enter your ToDo item',
                      ),
                      controller: eCtrl,
                    ),
                  ),
                  Consumer<ListModel>(
                    builder: (_, listModel, __) => FlatButton(
                      child: Text('Add'),
                      onPressed: () {
                        if (eCtrl.text != '') {
                          Map<String, dynamic> item = {
                            'value': false,
                            'text': eCtrl.text
                          };
                          listModel.addItem(item);
                          eCtrl.clear();
                        }
                      },
                    ),
                  ),
                ],
              ),
            ),
            Center(
              child: Consumer<ListModel>(builder: (_, listModel, __) {
                var items = listModel.getItems;
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(
                      height: 300,
                      child: ListView.builder(
                        itemCount: items.length,
                        itemBuilder: (BuildContext context, int idx) =>
                            Container(
                          padding: const EdgeInsets.all(5),
                          color: Colors.green,
                          child: Row(
                            children: <Widget>[
                              Checkbox(
                                  value: items[idx]['value'],
                                  onChanged: (val) {
                                    listModel.toggleValue(idx, val);
                                  }),
                              Text(
                                items[idx]['text'],
                                style: TextStyle(
                                    fontSize: 21, color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ],
                );
              }),
            ),
          ],
        ),
      ),
    );
  }
}

list_model.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class ListModel with ChangeNotifier {
  List<Map<String, dynamic>> _items = [];

  List<Map<String, dynamic>> get getItems => _items;

  void addItem(Map<String, dynamic> item) {
    _items.add(item);
    notifyListeners();
  }

  void toggleValue(int idx, bool val) {
    _items[idx]['value'] = val;
    notifyListeners();
  }
}

2 个答案:

答案 0 :(得分:0)

如自述文件中通过以下链接所述

https://pub.dev/packages/flutter_secure_storage

以下代码实例化存储,并且以下代码必须位于async方法中,因为这将返回将来。

final storage = new FlutterSecureStorage();

您可以将_items列表作为值传递,并且可以设置一些键名

await storage.write(key: key, value: _items);

然后您可以使用密钥名称(在存储时设置)获取该值

List<Map<String, dynamic>> _value = await storage.read(key: key);

然后您可以映射从存储中获取的_value并将其存储在_items中。然后,您现在就可以对应用中的所有数据进行各种操作和查询。

记笔记!我没有在代码库中尝试过这种方法。我只是说了我的想法。请在您的代码中尝试使用此代码,然后对我发表评论。

以下代码在模型中使用此代码正确执行,用于存储数据:

Future<void> _storingData() async {
    final storage = new FlutterSecureStorage();

    for (int i = 0; i < _items.length; i++) {
        await storage
              .write(key: _items[i]['text'], value: "${_items[i]['value']}")
              .then((value) => print("success"));
    }
}

用于检索数据:

Future<void> retrivingData() async {
    final storage = new FlutterSecureStorage();
    Map<String, String> allValues = await storage.readAll();

    print(allValues);

    allValues.forEach((key, value) {
        bool val = bool.fromEnvironment(value, defaultValue: false);
        Map<String, dynamic> item = {'value': val, 'text': key};
        addItem(item);
    });
}

最后,我再次将所有值存储到列表中。

您应根据使用情况,根据上述方法对main.dart中的代码进行一些更改。

答案 1 :(得分:0)

您可以在下面复制粘贴运行完整代码
您可以使用类TodoItem并使用JSON字符串保存/加载
Provider用于安全存储的逻辑是完整代码,太长,无法描述细节
代码段

List<TodoItem> todoItemFromJson(String str) =>
    List<TodoItem>.from(json.decode(str).map((x) => TodoItem.fromJson(x)));

String todoItemToJson(List<TodoItem> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class TodoItem {
  TodoItem({
    this.item,
    this.checked,
  });

  String item;
  bool checked;

  factory TodoItem.fromJson(Map<String, dynamic> json) => TodoItem(
        item: json["item"],
        checked: json["checked"],
      );

  Map<String, dynamic> toJson() => {
        "item": item,
        "checked": checked,
      };
}

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

import 'dart:convert';

List<TodoItem> todoItemFromJson(String str) =>
    List<TodoItem>.from(json.decode(str).map((x) => TodoItem.fromJson(x)));

String todoItemToJson(List<TodoItem> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class TodoItem {
  TodoItem({
    this.item,
    this.checked,
  });

  String item;
  bool checked;

  factory TodoItem.fromJson(Map<String, dynamic> json) => TodoItem(
        item: json["item"],
        checked: json["checked"],
      );

  Map<String, dynamic> toJson() => {
        "item": item,
        "checked": checked,
      };
}

class ListModel with ChangeNotifier {
  FlutterSecureStorage _storage;

  List<TodoItem> _items = [];

  List<TodoItem> get getItems => _items;

  initilaize() async {
    print("initialize");
    String jsonString = await _storage.read(key: "todo");
    if (jsonString != null) {
      _items = todoItemFromJson(jsonString);
      notifyListeners();
    }
  }

  ListModel.init(FlutterSecureStorage storage) {
    print("init");
    _storage = storage;
    initilaize();
  }

  void update(FlutterSecureStorage storage) {
    print("update");
    _storage = storage;
  }

  void addItem(TodoItem item) {
    _items.add(item);
    notifyListeners();
  }

  void toggleValue(int idx, bool val) {
    _items[idx].checked = val;
    notifyListeners();
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MultiProvider(
        providers: [
          Provider<FlutterSecureStorage>(create: (_) => FlutterSecureStorage()),
          ChangeNotifierProxyProvider<FlutterSecureStorage, ListModel>(
            create: (_) {
              return ListModel.init(
                  Provider.of<FlutterSecureStorage>(_, listen: false));
            },
            update: (_, storage, listModel) => listModel..update(storage),
          ),
        ],
        child: MyHomePage('Todos app example'),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage(this.title);

  final String title;

  final TextEditingController eCtrl = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        actions: <Widget>[
          Consumer2<ListModel, FlutterSecureStorage>(
              builder: (_, listModel, storage, __) => IconButton(
                    icon: Icon(Icons.save),
                    onPressed: () async {
                      await storage.write(
                          key: "todo", value: todoItemToJson(listModel._items));
                      print("save done");
                    },
                  ))
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      decoration: InputDecoration(
                        border: InputBorder.none,
                        hintText: 'Enter your ToDo item',
                      ),
                      controller: eCtrl,
                    ),
                  ),
                  Consumer<ListModel>(
                    builder: (_, listModel, __) => FlatButton(
                      child: Text('Add'),
                      onPressed: () {
                        if (eCtrl.text != '') {
                          Map<String, dynamic> item = {
                            'value': false,
                            'text': eCtrl.text
                          };
                          listModel.addItem(
                              TodoItem(item: eCtrl.text, checked: false));
                          eCtrl.clear();
                        }
                      },
                    ),
                  ),
                ],
              ),
            ),
            Center(
              child: Consumer<ListModel>(builder: (_, listModel, __) {
                var items = listModel.getItems;
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(
                      height: 300,
                      child: ListView.builder(
                        itemCount: items.length,
                        itemBuilder: (BuildContext context, int idx) =>
                            Container(
                          padding: const EdgeInsets.all(5),
                          color: Colors.green,
                          child: Row(
                            children: <Widget>[
                              Checkbox(
                                  value: items[idx].checked,
                                  onChanged: (val) {
                                    listModel.toggleValue(idx, val);
                                  }),
                              Text(
                                items[idx].item,
                                style: TextStyle(
                                    fontSize: 21, color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ],
                );
              }),
            ),
          ],
        ),
      ),
    );
  }
}