dart 根据其他小部件(我的情况下为抽屉)的设置(提供者数据)更新当前小部件的数据显示?

fv2wmkja  于 2023-05-04  发布在  其他
关注(0)|答案(1)|浏览(111)

所以我有一个抽屉小部件,我保留并修改我的应用程序的一些设置。在主屏幕上我有标签。当我点击其中一个标签时,一个子部件会显示一些数字数据。在我的抽屉里,我设置了数字应该显示为指数还是正常。该设置与共享首选项一起记录。当我重新启动应用程序时,我确认设置已保留。我显示的数据与设置从供应商,但它不会立即改变,当我改变我的设置从抽屉。当我重新启动应用程序时,我观察到数据根据设置正确显示,但在更改设置时没有立即显示。如何根据其他小部件中更改的设置更新我的子有状态小部件行为?Full behaviourFull code->(无论我做了什么,我得到了愚蠢的代码格式不正确的错误。Ctrl+M,手动添加4个空格等)
pubspec.yaml

dependencies:
      flutter:
        sdk: flutter
      provider: 
      shared_preferences:

main.dart

import 'package:flutter/material.dart';
    import 'myhomepage.dart';
    import 'package:provider/provider.dart';
    import 'dummyprovider.dart';

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

    class MyApp extends StatelessWidget {
      const MyApp({super.key});
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            ChangeNotifierProvider(create: (context) => SettingsProvider()),
          ],
          child: MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: const MyHomePage(title: 'Flutter Demo Home Page'),
          ),
        );
      }
    }

dummyprovider.dart

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

    class SettingsProvider with ChangeNotifier {
      late SharedPreferences _sharedPrefs;
      bool _displayValuesAsScientific = false;

      SettingsProvider() {
        initialState().then((value) {
          debugPrint("settingsprovider.dart, initialStatecalledthen");
          getValueDisplaySetting();
        });
      }

      Future<void> initialState() async {
        _sharedPrefs = await SharedPreferences.getInstance();
      }

      getValueDisplaySetting() {
        _displayValuesAsScientific = _sharedPrefs.getBool("settingExponential") ?? false;
        notifyListeners();
      }

      setValueDisplaySetting(bool value) {
        _sharedPrefs.setBool("settingExponential", value);
        debugPrint("settingsprovider.dart, setValueDisplaySetting as $value");
        notifyListeners();
      }

      bool get displaySetting {
        return _displayValuesAsScientific;
      }
    }

myhomepage.dart

import 'package:flutter/material.dart';
    import 'package:provider/provider.dart';
    import 'dummyprovider.dart';
    import 'child.dart';
    import 'appdrawer.dart';

    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key, required this.title});
      final String title;
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
      String numberOne = "12021321.2131";
      String numberTwo = "1233.123";
      String numberToShow = "1";
      @override
      Widget build(BuildContext context) {
        final sElement = context.watch<SettingsProvider>();
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          drawer: AppDrawer(),
          body: Center(
            child: Column(
              children: <Widget>[
                Container(
                  height: 50,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      SizedBox(width: MediaQuery.of(context).size.width * 0.05),
                      GestureDetector(
                        onTap: (() {
                          setState(() {
                            numberToShow = numberOne;
                          });
                        }),
                        child: Container(
                          width: MediaQuery.of(context).size.width * 0.45,
                          color: Colors.black,
                          child: Center(
                            child: Text(
                              "$numberOne",
                              style: const TextStyle(
                                fontWeight: FontWeight.bold,
                                color: Colors.blue,
                              ),
                            ),
                          ),
                        ),
                      ),
                      GestureDetector(
                        onTap: (() {
                          setState(() {
                            numberToShow = numberTwo;
                          });
                        }),
                        child: Container(
                          width: MediaQuery.of(context).size.width * 0.45,
                          color: Colors.amberAccent,
                          child: Center(
                            child: Text(
                              "$numberTwo",
                              style: const TextStyle(
                                fontWeight: FontWeight.bold,
                                color: Colors.red,
                              ),
                            ),
                          ),
                        ),
                      ),
                      SizedBox(width: MediaQuery.of(context).size.width * 0.05),
                    ],
                  ),
                ),
                const Text(
                  'Data to show:',
                ),
                Expanded(
                  child: ChildWidget(numberToShow),
                )
              ],
            ),
          ),
        );
      }
    }

appdrawer.dart

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

    class AppDrawer extends StatefulWidget {
      @override
      State<AppDrawer> createState() => _AppDrawerState();
    }

    class _AppDrawerState extends State<AppDrawer> {
      bool introScreen = false;
      String intropref = "false";
      SharedPreferences? appPreferences;
      bool vibrateSetting = false;
      bool settingExponential = false;

      @override
      void initState() {
        super.initState();
        setPrefs();
      }

      void setPrefs() async {
        appPreferences = await SharedPreferences.getInstance();
        loadPrefIntroSc();
        setState(() {
          settingExponential = Provider.of<SettingsProvider>(context, listen: false).displaySetting;
        });
      }

      void loadPrefIntroSc() async {
        introScreen = appPreferences!.getBool("skipIntro") ?? false;
        vibrateSetting = appPreferences!.getBool("vibrateSetting") ?? false;
      }

      Future<String> getDefaultIntroSetting() async {
        return "gotScreenSetting";
      }

      refresh() {
        setState(() {});
      }

      @override
      Widget build(BuildContext context) {
        var sElement = context.watch<SettingsProvider>();
        return Drawer(
          child: ListView(
            children: [
              FutureBuilder(
                future: getDefaultIntroSetting(),
                builder: (context, snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.waiting:
                      return const Center(
                        child: CircularProgressIndicator(),
                      );
                    case ConnectionState.active:
                      return const Text("active");
                    case ConnectionState.none:
                      return const Text("none");
                    case ConnectionState.done:
                      return Column(
                        children: [
                          // setting for exponential display
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              const SizedBox(
                                width: 10,
                              ),
                              Container(
                                child: const Text(
                                  "Show as exponential",
                                  style: TextStyle(
                                    color: Colors.black,
                                  ),
                                ),
                              ),
                              Flexible(
                                child: Container(),
                              ),
                              Switch(
                                  value: settingExponential,
                                  onChanged: (value) {
                                    sElement.setValueDisplaySetting(value);
                                    settingExponential = value;
                                  }),
                              const SizedBox(
                                width: 10,
                              ),
                            ],
                          ),
                        ],
                      );
                    default:
                      return const Text("default");
                  }
                },
              ),
            ],
          ),
        );
      }
    }

child.dart

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

    class ChildWidget extends StatefulWidget {
      String dataToProcess;
      ChildWidget(this.dataToProcess, {Key? key}) : super(key: key);
      @override
      State<ChildWidget> createState() => _ChildWidgetState();
    }

    class _ChildWidgetState extends State<ChildWidget> {
      @override
      Widget build(BuildContext context) {
        final sElement = context.watch<SettingsProvider>();
        return Center(
          child: Text(
            sElement.displaySetting
                ? double.parse(widget.dataToProcess) > 100000 ||
                        double.parse(widget.dataToProcess) < 0.00001
                    ? double.parse(widget.dataToProcess).toStringAsExponential()
                    : double.parse(widget.dataToProcess).toString()
                : double.parse(widget.dataToProcess).toStringAsFixed(5),
            style: Theme.of(context).textTheme.headline4,
          ),
        );
      }
    }

子部件应立即更新数据显示方法,更改设置。

0g0grzrc

0g0grzrc1#

因此,似乎即使我“观看”provider的值,在“setValueDisplaySetting()”方法中,我在调用“notifyListeners()”方法之前忘记将值分配给provider变量“_displayValuesAsScientific”,所以dummyprovider.dart应该是这样的:

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

class SettingsProvider with ChangeNotifier {
  late SharedPreferences _sharedPrefs;
  bool _displayValuesAsScientific = false;

  SettingsProvider() {
    initialState().then((value) {
      debugPrint("settingsprovider.dart, initialStatecalledthen");
      getValueDisplaySetting();
    });
  }

  Future<void> initialState() async {
    _sharedPrefs = await SharedPreferences.getInstance();
  }

  getValueDisplaySetting() {
    _displayValuesAsScientific = _sharedPrefs.getBool("settingExponential") ?? false;
    notifyListeners();
  }

  setValueDisplaySetting(bool value) {
    _sharedPrefs.setBool("settingExponential", value);
    debugPrint("settingsprovider.dart, setValueDisplaySetting as $value");
    _displayValuesAsScientific = value // THIS ADDED!!!!
    notifyListeners();
  }

  bool get displaySetting {
    return _displayValuesAsScientific;
  }
}

相关问题