首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于SharedPreferences的颤振载荷变量

基于SharedPreferences的颤振载荷变量
EN

Stack Overflow用户
提问于 2022-06-28 14:36:57
回答 2查看 86关注 0票数 0

我正在学习如何在颤振中使用SharedPreferences库。

我创建了这段代码,当我关闭并重新打开应用程序时,我希望计数器和counter2变量保留为最后一次保存。

但是,当我重新打开应用程序时,计数器和counter2值将返回到0。有人能向我解释一下我哪里出了问题吗?

谢谢。

代码语言:javascript
运行
复制
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'data.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int counter = 0;
  int counter2 = 0;

  increment() {
    setState(() {
      counter += 1;
      counter2 += 2;
    });
  }

  loadData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    setState(() {
      String? json = prefs.getString('UserData');
      print('loaded json: $json');

      if (json == null) {
        print('NO DATA (null)');
      } else {
        Map<String, dynamic> map = jsonDecode(json);
        print('map $map');
        final data = Data.fromJson(map);
        print('Data ${data.counter}, ${data.counter2}');
      }
    });
  }

  saveData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    final _data = Data(counter: counter, counter2: counter2);

    String json = jsonEncode(_data);
    print('saved json: $json');
    prefs.setString('UserData', json);
  }

  clearData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.clear();
    print('data cleared');
  }

  /// dichiarare l' initState()
  @override
  void initState() {
    super.initState();
    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              'c: $counter, c2: $counter2',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          increment();
          saveData();
        },
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
代码语言:javascript
运行
复制
class Data {
  int counter = 0;
  int counter2 = 0;

  Data({required this.counter, required this.counter2});

  Map<String, dynamic> toJson() {
    return {
      'counter': counter,
      'counter2': counter2,
    };
  }

  Data.fromJson(Map<String, dynamic> json) {
    counter = json['counter'];
    counter2 = json['counter2'];
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-06-28 16:06:05

我同意另一个答案,最好是使用FutureBuilder。但是,可以使当前代码只需在loadData末尾添加两行代码即可。

代码语言:javascript
运行
复制
loadData() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();

  setState(() {
    String? json = prefs.getString('UserData');
    print('loaded json: $json');

    if (json == null) {
      print('NO DATA (null)');
    } else {
      Map<String, dynamic> map = jsonDecode(json);
      print('map $map');
      final data = Data.fromJson(map);
      print('Data ${data.counter}, ${data.counter2}');

      // add these lines
      counter = data.counter;
      counter2 = data.counter2;
    }
  });
}

所发生的事情(另一个答案是)是,您的小部件最初是在不知道来自SharedPreferences的值的情况下构建的。在第一个构建完成一段时间之后,loadData的未来就完成了,并使用setState重新构建了这个小部件。

在实际应用程序中,您希望避免不必要的构建,因此您宁愿在加载异步数据时显示进度指示符,请检查FutureBuilder

票数 2
EN

Stack Overflow用户

发布于 2022-06-28 16:00:19

一个简单的答案是,当您在loadData();中调用initState时,函数是相对于小部件的其余部分异步执行的,因此您的Scaffold是在数据可用之前构建的。这就是为什么你看到的数据是从你的print,而不是在应用程序。

解决这个问题的一种方法是给我们一个https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72788463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档