Dart 中的全局变量

Global Variables in Dart

我尝试创建一个 Dart 单页应用程序。

我创建了第一个包含整个应用程序的自定义元素 (custom-application)。 它有一个容器,用于呈现视图。还有一个侧面导航,它将包含用户信息并在用户登录时更新。

我想在视图之间共享信息。 我如何在 custom-application 中定义一个全局变量并能够与其他视图共享它?

例如,当您启动应用程序时,您未通过身份验证。当您调用 /login (login-view) 时,您将拥有一个登录表单。我想,当您登录应用程序时,custom-application 元素存储由嵌套视图加载的用户信息 login-view 并更新侧导航。

可以吗?

只需创建一个库文件并为您需要的全局变量创建字段。在需要访问这些字段的任何地方导入此库。

app.dart

import 'globals.dart' as globals;

main() {
  globals.isLoggedIn = true;
}

component1.dart

import 'globals.dart' as globals;

class MyComponent {
  view() {
    if(globals.isLoggedIn) {
      doSomething();
    else {
      doSomethingElse();
    }
  }
}

globals.dart

library my_prj.globals;

bool isLoggedIn = false;

你也可以

  • 在全局库中创建一个单例(有关详细信息,请参阅 How do you build a Singleton in Dart?)。
  • 使用 observable 获取有关更改的通知(有关详细信息,请参阅 Implement an Observer pattern in Dart,

++++ 2019 年 7 月更新 ++++

我写了一个集成Flutter Global Config的Package

EZ Flutter 是小部件、包和许多其他有用东西的集合,混合在一个小框架中。目的是从头开始提供标准功能。 EZ Flutter 支持管理可在应用程序内部访问的不同配置文件。

Github : https://github.com/Ephenodrom/EZ-Flutter

dependencies:
  ez_flutter: ^0.2.0

查看文档如何使用不同的配置。

https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/APPLICATION_SETTINGS.md

++++ 旧答案++++

我对全局变量有同样的问题。因此,我还需要为每个应用程序版本 (dev / prod) 进行不同的配置,我不想在 main_dev.dart 或 main_prod.dart 文件中编写配置。

我写了一个简单的 flutter 包来处理分离的配置文件并在应用程序启动时加载它们。然后,您的应用中的每一行代码都可以使用该配置。

https://github.com/Ephenodrom/Flutter-Global-Config

使用方法:

在assets/cfg/$file.json

下创建一个json文件

将 assets/cfg 添加到您的 pubspec.yaml

在应用程序启动时加载不同的配置文件:

import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';

void main() async{
  await GlobalConfiguration().loadFromAsset("app_settings");
  await GlobalConfiguration().loadFromAsset("env_dev_settings");
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  ...
}

在您的应用中使用配置:

import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';

class CustomWidget extends StatelessWidget {

    CustomWiget(){
        // Access the config in the constructor
        print(GlobalConfiguration().getString("key1"); // prints value1
    }

    @override
     Widget build(BuildContext context) {
        // Access the config in the build method
        return new Text(GlobalConfiguration().getString("key2"));
     }
}

您可以创建 class

myColors.dart

class AppColors {

  static var primary = Colors.blue;
}

并导入您的 class

import 'package:myapp/.../myColors.dart';

并通过 AppColors.primary

访问

基于库的想法,这里有一种方法可以将 "keyed" 任何类型的全局变量添加到从其他小部件调用的映射中。这样您就不必事先声明此类变量。如果变量不存在,它会被 appDataSet 添加到地图中。 因此,在像复选框这样的小部件中,您可以在 setState() 函数中添加例如:appDataSet('aCheckBox',value);如果地图中不存在 aCheckBox,则会添加它,并使用值(在本例中为布尔值)加载该值。

library my_prj.globals;

Map appData = Map<String,dynamic>();

void appDataSet(String key, dynamic value) {
  if (!appData.containsKey(key))
    appData.putIfAbsent(key, () => value);
  else
    appData.update(key, (dynamic) => value);
  print(appData);
}

dynamic appDataGet(String key) {
  if (appData.containsKey(key))
    return (appData.putIfAbsent(key, () => {}));
  else
    return (null);
}

您只需要创建一个类似“constants.dart”的文件

import '...materials.dart';

const Color baseColor = Color(0XFF353535);

并像这样使用

import '...constants.dart';
.......
......


....
Container(
color: baseColor,
.....

),

我创建了一个名为 my-globals.dart 的 dart 文件,我可以在其中定义我的全局变量。

像这样:

library globals;

int globalInt = 0;
bool globalBoolean = true;
String globalString = "";
double globalDouble= 10.0;

这就是整个 dart 文件。

然后,在同一目录或文件夹中,我可以创建其他 classes,我可以在其中通过将 my-globals.dart 作为全局变量导入来访问我的全局变量。让我们创建一个扩展 StatefulWidget 的 class。在那里,我们将通过按下 Flatbutton 来更改名为 globalInt 的全局变量的值。

import 'package:flutter/material.dart';
import 'my-globals.dart' as globals;

class OtherClass extends StatefulWidget {
  OtherClass({Key key}) : super(key: key);

  @override
  _OtherClassState createState() => _OtherClassState();
}

class _OtherClassState extends State<OtherClass> {
  @override
  Widget build(BuildContext context) {
    return Container(
       child: FlatButton(
         color: Colors.blue,
         textColor: Colors.white,
         onPressed: () {
            setState(() {globals.globalInt++;});
            print(globals.globalInt);
         },
       ),
    );
  }
}

你看。我只是通过编写全局变量来访问我想要的变量。然后是库中包含的变量的名称。

希望这个例子有助于更好地理解如何使用全局库。

全局变量通常不受欢迎。推荐的 flutter 解决方案是提供程序库。它只是一个小部件,您可以将其插入小部件树中某处的某个位置并赋予它一些值(对象,class)来保存。然后,您可以更深入地访问其他小部件中的值。

与全局变量相反,您可以修改提供程序存储的值,内部的小部件将重新呈现。

pub.dev/provider

店铺价值

  Widget build(BuildContext context) {
    String someValue = '5';
    return Provider(
            create: (_) => someValue),
            child: SafeArea(...)
    );
  }

获取值:

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

    WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
      setState(() {
        value5 = context.read<String>();
      });
    });
  }