flutter-带有共享流量的负载变量

发布于 2025-02-11 04:36:44 字数 3287 浏览 2 评论 0原文

我正在学习如何在Flutter中使用共享流程库。

我创建了此代码,一旦我关闭并重新打开应用程序保存作为最后一个保存,我希望计数器和计数器变量。

但是,当我重新打开应用程序时,计数器和counter2值返回为0。 谁能向我解释我出错的地方?

谢谢。

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.
    );
  }
}

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'];
  }
}

I am learning how to use the SharedPreferences library in Flutter.

I created this code and I would like the counter and counter2 variables once I close and reopen the app to remain as the last save.

However, when I reopen the app the counter and counter2 values return to 0.
Can anyone explain to me where I am going wrong?

Thank you.

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.
    );
  }
}

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'];
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美人如玉 2025-02-18 04:36:44

I agree with the other answer, the best is to use a FutureBuilder.但是,您可以通过简单地在loaddata的末尾添加两行来使当前代码工作:

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

I agree with the other answer, the best is to use a FutureBuilder. But you can make your current code work with simply adding two lines at the end of loadData:

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;
    }
  });
}

What happens (as the other answer says) is that your widget is first built without knowing the values from SharedPreferences. After a little time this first build is done, the loadData future completes, and with setState the widget is rebuilt.

In a real application you'd like to avoid unnecessary builds, so you'd rather display a progress indicator while async data is being loaded, check FutureBuilder.

纸伞微斜 2025-02-18 04:36:44

一个简短的答案是,当您调用loaddata();内部 initstate 该函数相对于窗口小部件的其余部分都异步执行,因此您的脚手架是在数据为之前构建的可用的。这就是为什么您从print中看到数据,但在应用程序中却没有。

解决问题的一种方法是a https://api.flutter.dev /flutter/widgets/futurebuilder-class.html

A short answer is that when you call loadData(); inside initState the function is performed asynchronously relative to the rest of the widget, so your Scaffold is built before the data is available. This is why you are seeing the data in from your print but not in the app.

One way to address it is to us a https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文