我尝试创建一个Dart单页应用程序。
我创建了一个包含整个应用程序的第一个自定义元素(custom-application
(。它有一个用于呈现视图的容器。还有一个侧边导航,它将包含用户信息并在用户登录时更新。
我想在视图之间共享信息。如何在custom-application
中定义全局变量并能够与其他视图共享?
例如,当您启动应用时,您不会进行身份验证。当您调用/login ( login-view
( 时,您将拥有一个登录表单。我希望,当您登录应用程序时,custom-application
元素存储嵌套视图加载的用户信息login-view
并更新侧面导航。
有可能做到吗?
只需创建一个库文件并为您需要的全局变量创建字段即可。在需要访问这些字段的任何位置导入此库。
应用达特
import 'globals.dart' as globals;
main() {
globals.isLoggedIn = true;
}
组件1.飞镖
import 'globals.dart' as globals;
class MyComponent {
view() {
if(globals.isLoggedIn) {
doSomething();
else {
doSomethingElse();
}
}
}
全球达特
library my_prj.globals;
bool isLoggedIn = false;
你也可以
- 在全局库中创建单例(有关更多详细信息,请参阅如何在 Dart 中构建单例?(。
- 使用可观察获取有关更改的通知(有关更多详细信息,请参阅在 Dart 中实现观察者模式,如何在类中触发一种 onChange 事件(
您可以创建类
myColors.dart
class AppColors {
static var primary = Colors.blue;
}
和导入您的类
import 'package:myapp/.../myColors.dart';
并AppColors.primary
访问
我创建了一个名为my-globals.dart的dart文件,我可以在其中定义我的全局变量。
喜欢这个:
library globals;
int globalInt = 0;
bool globalBoolean = true;
String globalString = "";
double globalDouble= 10.0;
这就是整个飞镖文件。
然后,在同一目录或文件夹中,我可以创建其他类,我可以通过将 my-globals.dart 导入为全局变量来访问我的全局变量。让我们创建一个扩展 StatefulWidget 的类。在那里,我们将通过按 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);
},
),
);
}
}
你看。我只是通过编写全局变量来访问我想要的变量。然后是库中包含的变量的名称。
希望这个例子有助于更好地理解如何使用全局库。
更新 2019 年 7 月 ++++
我写了一个集成了 Flutter 全局配置的包。
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文件中编写配置。
我写了一个简单的颤振包,处理单独的配置文件并在应用程序启动时加载它们。然后,配置可在应用中的每一行代码中使用。
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"));
}
}
您所需要的只是创建一个类似"constants.dart"的文件
import '...materials.dart';
const Color baseColor = Color(0XFF353535);
并像这样使用
import '...constants.dart';
.......
......
....
Container(
color: baseColor,
.....
(,
基于库的想法,这里有一种方法可以将任何类型的"键控"全局变量添加到从其他小部件调用的地图中。这样,您就不必事先声明此类变量。如果变量不存在,则由 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);
}
全局变量通常不受欢迎。Flutter 的推荐解决方案是提供程序库。它只是一个小部件,你插入小部件树中的某个位置,并给它一些值(对象、类(来保存。然后,您可以在其他小部件中更深入地访问该值。
与全局变量相反,您可以修改提供程序存储的值,内部深处的小部件将重新渲染。
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>();
});
});
}