使用共享首选项与更改通知器

huangapple go评论84阅读模式
英文:

using Shared preferences with a change notifier

问题

我正在尝试理解如何在使用共享首选项(shared preferences)与更改通知器(change notifier)时使用它。我已经创建了一个基本的应用程序,我想使用共享首选项从更改通知器中保存一个布尔值和一个字符串。以下是您提供的代码的翻译部分:

main.dart中的更改:

import 'package:shared_preferences/shared_preferences.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => GlobalSettings1(prefs: SharedPreferences.getInstance())),
        ChangeNotifierProvider(create: (_) => SectionSettings1()),
      ],
      child: MyApp(),
    ),
  );
}

// ... 其他代码不变

在上述更改中,您需要为ChangeNotifierProvider提供GlobalSettings1类的一个实例,但是您需要传递一个名为prefs的参数,它是SharedPreferences的实例。在这里,我使用SharedPreferences.getInstance()来获取SharedPreferences实例。

另外,确保导入所需的包,以便SharedPreferences可以正常工作。然后,您可以在需要时访问SharedPreferences实例以保存和读取数据。

希望这有助于解决您的问题。如果您有任何其他疑问或需要进一步的帮助,请随时提问。

英文:

I'm trying to understand how to use shared preferences with a change notifier. I've created a basic app and I want to save a bool and a string from the change notifier using shared preferences.
here is my main.dart:

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

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => GlobalSettings1()),
        ChangeNotifierProvider(create: (_) => SectionSettings1()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        initialRoute: '/seventh',
        routes: {
          '/': (context) => Page01(),
          '/first': (context) => Page02(),
          '/second': (context) => Page03(),
        });
  }
}

and here is page01

class _Page01State extends State<Page01> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          InkWell(
            onTap: () {
              context.read<GlobalSettings1>().ToggleSwitch();
            },
            child: Container(
              height: 30,
              width: 80,
              color: context.watch<GlobalSettings1>().toggleSwitch01
                  ? Colors.green
                  : Colors.red,
            ),
          ),
          SizedBox(
            height: 20,
          ),
          InkWell(
              onTap: () {
                showDialog(
                  context: context,
                  builder: (BuildContext context) => Material(
                    color: Colors.transparent,
                    child: Buttons(
                      onTap: (val) {
                        context.read<GlobalSettings1>().StringToSave(val);
                        Navigator.pop(context);
                      },
                    ),
                  ),
                );
              },
              child: Container(
                height: 30,
                width: 80,
                child: Center(
                  child: Text(
                    context.watch()<GlobalSettings1>().stringToSave,
                  ),
                ),
              )),
        ],
      ),
    );
  }
}

and finally, here is my change notifier:

class Buttons extends StatelessWidget {
  const Buttons({Key? key, required this.onTap}) : super(key: key);
  final ValueChanged? onTap;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        InkWell(
            onTap: () {
              if (onTap != null) {
                onTap!('Choice01');
              }
            },
            child: Container(
              height: 30,
              width: 80,
              child: Text('Choice01'),
            )),
        SizedBox(
          height: 30,
        ),
        InkWell(
            onTap: () {
              if (onTap != null) {
                onTap!('Choice02');
              }
            },
            child: Container(
              height: 30,
              width: 80,
              child: Text('Choice02'),
            )),
      ],
    );
  }
}

class GlobalSettings1 with ChangeNotifier {
  bool _toggleSwitch01 = true;
  String _stringToSave = 'Choice01';

  final SharedPreferences prefs;

  GlobalSettings1({required this.prefs});

  bool get toggleSwitch01 => _toggleSwitch01;
  String get stringToSave => _stringToSave;

  void ToggleSwitch() {
    _toggleSwitch01 = !_toggleSwitch01;
    _setPrefItems();
    notifyListeners();
  }

  void StringToSave(val) {
    _stringToSave = val;
    _setPrefItems();
    notifyListeners();
  }

  void _setPrefItems() {
    prefs.setBool('toggleSwitch01', _toggleSwitch01);
    prefs.setString('stringToSave', _stringToSave);
    notifyListeners();
  }

  void _getPrefItems() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _stringToSave = prefs.getString('stringToSave') ?? '';
    _toggleSwitch01 = prefs.getBool('autoUpdateVariables') ?? true;
    notifyListeners();
  }

  bool getToggleSwitch01() {
    _getPrefItems();
    return _toggleSwitch01;
  }

  String getStringToSave() {
    _getPrefItems();
    return _stringToSave;
  }
}

As you can see, there is a bool that is toggled in Page01 and a String that is displayed from a value that is generated and passed through from the buttons widget.

After looking at other tutorials on this matter, I think i have the change notifier set up correctly but am unsure about how to set up the main.dart and Page01 so that when the bool and String are set, they stay like that when the app is rebooted.

i'm currently getting an error in main.dart:

ChangeNotifierProvider(create: (_) => GlobalSettings1()),

asking me to add required argument prefs but i'm unsure what the code should be to go in the brackets.

thanks so much and any help would be greatly appreciated.

答案1

得分: 1

你需要将SharedPreferences的实例传递给你的GlobalSettings1,同时将GlobalSettings1更改为以下内容:

class GlobalSettings1 with ChangeNotifier {
  bool _toggleSwitch01 = true;
  String _stringToSave = 'Choice01';

  final SharedPreferences prefs;

  GlobalSettings1({required this.prefs});

  bool get toggleSwitch01 => _toggleSwitch01;
  String get stringToSave => _stringToSave;

  void ToggleSwitch() {
    _toggleSwitch01 = !_toggleSwitch01;
    _setPrefItems();
    notifyListeners();
  }

  void StringToSave(val) {
    _stringToSave = val;
    _setPrefItems();
    notifyListeners();
  }

  void _setPrefItems() {
    prefs.setBool('toggleSwitch01', _toggleSwitch01);
    prefs.setString('stringToSave', _stringToSave);
    notifyListeners();
  }

  void _getPrefItems() { // <=== 更改这里
    _stringToSave = prefs.getString('stringToSave') ?? '';
    _toggleSwitch01 = prefs.getBool('toggleSwitch01') ?? true;
    notifyListeners();
  }

  bool getToggleSwitch01() {
    _getPrefItems();
    return _toggleSwitch01;
  }

  String getStringToSave() {
    _getPrefItems();
    return _stringToSave;
  }
}

然后将你的main更改为以下内容:

void main() async {   
    SharedPreferences prefs = await SharedPreferences.getInstance();
    runApp(
        MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (_) => GlobalSettings1(prefs: prefs)),
            ChangeNotifierProvider(create: (_) => SectionSettings1()),
          ],
          child: MyApp(),
        ),
    );
}
英文:

You need pass an instance of SharedPreferences to your GlobalSettings1, also change GlobalSettings1 to this:

class GlobalSettings1 with ChangeNotifier {
  bool _toggleSwitch01 = true;
  String _stringToSave = &#39;Choice01&#39;;

  final SharedPreferences prefs;

  GlobalSettings1({required this.prefs});

  bool get toggleSwitch01 =&gt; _toggleSwitch01;
  String get stringToSave =&gt; _stringToSave;

  void ToggleSwitch() {
    _toggleSwitch01 = !_toggleSwitch01;
    _setPrefItems();
    notifyListeners();
  }

  void StringToSave(val) {
    _stringToSave = val;
    _setPrefItems();
    notifyListeners();
  }

  void _setPrefItems() {
    prefs.setBool(&#39;toggleSwitch01&#39;, _toggleSwitch01);
    prefs.setString(&#39;stringToSave&#39;, _stringToSave);
    notifyListeners();
  }

  void _getPrefItems() { // &lt;=== change this
    _stringToSave = prefs.getString(&#39;stringToSave&#39;) ?? &#39;&#39;;
    _toggleSwitch01 = prefs.getBool(&#39;autoUpdateVariables&#39;) ?? true;
    notifyListeners();
  }

  bool getToggleSwitch01() {
    _getPrefItems();
    return _toggleSwitch01;
  }

  String getStringToSave() {
    _getPrefItems();
    return _stringToSave;
  }
}

then change your main to this:

void main() {   
    SharedPreferences prefs = await SharedPreferences.getInstance();
    runApp(
        MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (_) =&gt; GlobalSettings1(prefs: prefs)),
            ChangeNotifierProvider(create: (_) =&gt; SectionSettings1()),
          ],
          child: MyApp(),
        ),
    );
}

答案2

得分: 0

Currently, you are passing an instance on constructor.

 GlobalSettings1({required this.prefs});

While it is SharedPreferences you can do get instance with

class GlobalSettings1 with ChangeNotifier {
  bool _toggleSwitch01 = true;
  String _stringToSave = 'Choice01';

  GlobalSettings1();

  ......

  void _setPrefItems() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool('toggleSwitch01', _toggleSwitch01);
    prefs.setString('stringToSave', _stringToSave);
    notifyListeners();
  }
英文:

Currently, you are passing an instance on constructor.

 GlobalSettings1({required this.prefs});

While it is SharedPreferences you can do get instance with

class GlobalSettings1 with ChangeNotifier {
  bool _toggleSwitch01 = true;
  String _stringToSave = &#39;Choice01&#39;;

  GlobalSettings1();

  ......

  void _setPrefItems() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool(&#39;toggleSwitch01&#39;, _toggleSwitch01);
    prefs.setString(&#39;stringToSave&#39;, _stringToSave);
    notifyListeners();
  }

huangapple
  • 本文由 发表于 2023年2月9日 00:18:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75388698.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定