内容整合

enum-> env

环境枚举配置

lib/enum/env.dart

1
enum Env { production, development, local }

config-> env_config

环境配置文件env_config!

lib/config/env_config.dart

env_config.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import 'package:flutter/material.dart';
import 'package:rent_house/enum/env.dart';

class EnvConfig extends InheritedWidget {
static Enum envName = Env.development; // 运行环境
static String appName = "好客租房"; // 系统名称
static String baseUrl = getBaseUrlByEnum(Env.development)!; // 基础url

/* const EnvConfig(
{super.key,
this.appName = "好客租房",
this.envName = Env.local,
this.baseUrl =
"https://www.fastmock.site/mock/04856e89f6ef8eca01f7bab4c6166bc6/rent_house/api/",
required super.child}); */
/*
构造函数不能直接 初始化静态属性
required this.appName,
'appName' is a static field in the enclosing class. Fields initialized in a constructor can't be static.
Try removing the initialization.
*/
EnvConfig({
super.key,
required String appName,
required Enum envName,
required String baseUrl,
required Widget child,
}) : super(child: child) {
EnvConfig.appName = appName;
EnvConfig.envName = envName;
EnvConfig.baseUrl = baseUrl;
}
static EnvConfig? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType(aspect: EnvConfig);
}

static bool? isProduction() => const bool.fromEnvironment("dart.vm.product");
// http://5d85ccfb1e61af001471bf60.mockapi.io
// https://www.fastmock.site/mock/04856e89f6ef8eca01f7bab4c6166bc6/rent_house
static List<Map<Enum, String>> baseUrlList = [
{
Env.production:
'https://www.fastmock.site/mock/04856e89f6ef8eca01f7bab4c6166bc6/rent_house/api/'
},
{
Env.development:
'https://www.fastmock.site/mock/240180fe470de74ae9e92a6e9a9f9d1e/rent_house_test/api/'
},
{
Env.local:
'https://www.fastmock.site/mock/240180fe470de74ae9e92a6e9a9f9d1e/rent_house_test/api/'
},
];

static String? getBaseUrlByEnum(Enum env) {
// var result = baseUrlList.firstWhere((e) => e[env]!.isNotEmpty)[env]; 错误写法 !.isNotEmpty 不能写这种bool条件
/*
var details = {'Usrname':'maxsu','Password':'******'};
print(details.isNotEmpty); true

var hosts = {};
print(hosts.isNotEmpty); false
isNotEmpty 判断的是{}空对象 而不是 null

element[env] != null
*/
/* Map<Enum, String> result =
baseUrlList.singleWhere((element) => element[env] != null);
result[env]; */
return baseUrlList.singleWhere((element) => element[env] != null)[env];
}

static String? getBaseUrl() {
var envEnum = isProduction()! ? Env.production : Env.development;
return getBaseUrlByEnum(envEnum);
}

// 更新应通知
@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) {
// TODO: implement updateShouldNotify
return false;
}
}

新建main环境入口文件

主要包含local.dart dev.dart prod.dart 分别为本地环境 开发环境 生产环境!

lib/main/*.dart

local.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import 'package:fconsole/fconsole.dart';
import 'package:flutter/material.dart';
import 'package:rent_house/app.dart';
import 'package:rent_house/config/env_config.dart';
import 'package:rent_house/enum/env.dart';

// import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
var configuredApp = EnvConfig(
appName: '好客煮饭local', // 项目名称 或者 app 名称
envName: Env.local, // 环境变量
baseUrl: EnvConfig.getBaseUrlByEnum(Env.local)!, // 接口基础地址
child: const App(),
);
// runApp(const App());
runAppWithFConsole(configuredApp);
}

dev.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import 'package:fconsole/fconsole.dart';
import 'package:flutter/material.dart';
import 'package:rent_house/app.dart';
import 'package:rent_house/config/env_config.dart';
import 'package:rent_house/enum/env.dart';

// import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
var configuredApp = EnvConfig(
appName: '好客煮饭dev', // 项目名称 或者 app 名称
envName: Env.development, // 环境变量
baseUrl: EnvConfig.getBaseUrlByEnum(Env.development)!, // 接口基础地址
child: const App(),
);
// runApp(const App());
runAppWithFConsole(configuredApp);
}

prod.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import 'package:flutter/material.dart';
import 'package:rent_house/app.dart';
import 'package:rent_house/config/env_config.dart';
import 'package:rent_house/enum/env.dart';

// import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
var configuredApp = EnvConfig(
appName: '好客煮饭prod', // 项目名称 或者 app 名称
envName: Env.production, // 环境变量
baseUrl: EnvConfig.getBaseUrlByEnum(Env.production)!, // 接口基础地址
child: const App(),
);
// runApp(const App());
runApp(configuredApp);
}

配置启动文件vscode

我这边idea用的vscode, 接下来需要配置下启动配置文件launch.json!

mac 用户: command + shift + p 打开 搜索窗口 输入 launch.json 打开文件!
windows 用户: ctrl + shift + p 打开 搜索窗口 输入 launch.json 打开文件!

配置内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"configurations": [
{
"name": "rent_house_local",
"type": "dart",
"request": "launch",
"program": "lib/main/local.dart"
},
{
"name": "rent_house_dev",
"type": "dart",
"request": "launch",
"program": "lib/main/dev.dart"
},
{
"name": "rent_house_prod",
"type": "dart",
"request": "launch",
"program": "lib/main/prod.dart"
},
]

结果如下:

接下来配置下dio baseUrl

lib/confg/http_config.dart

1
2
3
4
5
6
7
8
9
import 'env_config.dart';

class HTTPConfig {
// static const baseURL = "https://api.oioweb.cn";
// static const baseURL = "http://5d85ccfb1e61af001471bf60.mockapi.io";
static String? baseURL = EnvConfig.baseUrl;
static const timeout = 60 * 1000;
}

环境运行

  1. 通过vscode配置的启动文件!
  2. 通过flutter指定入口文件!
    启动命令
    1
    2
    3
    flutter run -t lib/main/local.dart
    flutter run -t lib/main/dev.dart
    flutter run -t lib/main/prod.dart
    打包命令
    1
    2
    3
    flutter build apk -t lib/main/local.dart
    flutter build apk -t lib/main/dev.dart
    flutter build apk

widget中使用

lib/app.dart

app.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import 'package:flutter/material.dart';

import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

import 'package:get/get.dart';
import 'package:rent_house/config/env_config.dart';
import 'package:rent_house/pages/unknow/index.dart';
import 'package:rent_house/router/app_pages.dart';
import 'package:rent_house/utils/storage/index.dart';

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

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
//设置尺寸(填写设计中设备的屏幕尺寸)如果设计基于360dp * 690dp的屏幕
/* ScreenUtil.init(
context,
// 设计稿大小
designSize: const Size(375, 812),
); */
EnvConfig.of(context);
print(
"envConfig appName ${EnvConfig.appName}",
);
print("envConfig baseUrl ${EnvConfig.baseUrl}");
print("envConfig envName ${EnvConfig.envName}");
// 设置全局 Loading 样式
EasyLoading.instance.indicatorType = EasyLoadingIndicatorType.chasingDots;
return ScreenUtilInit(
// designSize: const Size(720, 1280)
// 375, 812,
//设置初始化屏幕大小
designSize: const Size(375, 812),
builder: (context, child) => GetMaterialApp(
title: EnvConfig.appName,
theme: ThemeData(
// 主题颜色
primarySwatch: Colors.teal,
),
routingCallback: (routing) {
print('routingCallback value $routing ${routing!.current}');
print('routingCallback ${LocalStorage.get("authInfo")}');
},
// 配置国际化语言
locale: const Locale('zh'),
localizationsDelegates: const [
// FormBuilderLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('zh'), // 中文
Locale('en'), // 英文
],

// home: const LoginPage(),
// 未知路由
unknownRoute: GetPage(
name: Routes.UNKNOW,
page: () => const UnknowPage(),
transition: Transition.downToUp),
// 关闭 debugger 标签
debugShowCheckedModeBanner: false,
// 初始路由
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
// 默认路由动画
defaultTransition: Transition.rightToLeft,
builder: EasyLoading.init(),
),
);

/* return GetMaterialApp(
title: '好客租房Demo',
theme: ThemeData(
// 主题颜色
primarySwatch: Colors.teal,
),
// home: const LoginPage(),
// 未知路由
unknownRoute: GetPage(
name: Routes.UNKNOW,
page: () => const UnknowPage(),
transition: Transition.downToUp
),
// 关闭 debugger 标签
debugShowCheckedModeBanner: false,
initialRoute: AppPages.INITIAL,
getPages: AppPages.routes,
// 默认路由动画
defaultTransition: Transition.zoom,
builder: EasyLoading.init(),
); */
}
}