main.dart
6.35 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import 'package:dio/dio.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:oktoast/oktoast.dart';
import 'package:provider/provider.dart';
import 'package:quick_actions/quick_actions.dart';
import 'package:url_strategy/url_strategy.dart';
import 'package:flutter_gen/gen_l10n/one_poem_localizations.dart';
import 'home/splash_page.dart';
import 'net/dio_utils.dart';
import 'net/intercept.dart';
import 'provider/locale_provider.dart';
import 'provider/theme_provider.dart';
import 'res/constant.dart';
import 'routers/not_found_page.dart';
import 'routers/routers.dart';
import 'util/device_utils.dart';
import 'util/handle_error_utils.dart';
import 'util/log_utils.dart';
import 'util/theme_utils.dart';
///
/// 配置本地化的方法
/// 1. 安裝Flutter intl插件
/// 2. 執行 intl插件的初始化(tools->Flutter Intl->initialize for the Project)
/// 3. 創建i18n文件
/// 4. 执行:flutter gen-l10n --template-arb-file intl_en.arb --output-class OnePoemLocalizations letLocalizations --output-localization-file one_poem_localizations.dart
///
Future<void> main() async {
// debugProfileBuildsEnabled = true;
// debugPaintLayerBordersEnabled = true;
// debugProfilePaintsEnabled = true;
// debugRepaintRainbowEnabled = true;
/// 确保初始化完成
WidgetsFlutterBinding.ensureInitialized();
/// 去除URL中的“#”(hash),仅针对Web。默认为setHashUrlStrategy
/// 注意本地部署和远程部署时`web/index.html`中的base标签,https://github.com/flutter/flutter/issues/69760
setPathUrlStrategy();
/// sp初始化
await SpUtil.getInstance();
/// 1.22 预览功能: 在输入频率与显示刷新率不匹配情况下提供平滑的滚动效果
// GestureBinding.instance?.resamplingEnabled = true;
/// 异常处理
handleError(() => runApp(MyApp()));
/// 隐藏状态栏。为启动页、引导页设置。完成后修改回显示状态栏。
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom]);
// TODO(weilu): 启动体验不佳。状态栏、导航栏在冷启动开始的一瞬间为黑色,且无法通过隐藏、修改颜色等方式进行处理。。。
// 相关问题跟踪:https://github.com/flutter/flutter/issues/73351
}
class MyApp extends StatelessWidget {
MyApp({Key? key, this.home, this.theme}) : super(key: key) {
Log.init();
initDio();
Routes.initRoutes();
initQuickActions();
}
final Widget? home;
final ThemeData? theme;
static GlobalKey<NavigatorState> navigatorKey = GlobalKey();
void initDio() {
final List<Interceptor> interceptors = <Interceptor>[];
/// 统一添加身份验证请求头
interceptors.add(AuthInterceptor());
/// 刷新Token
interceptors.add(TokenInterceptor());
/// 打印Log(生产模式去除)
if (!Constant.inProduction) {
interceptors.add(LoggingInterceptor());
}
/// 适配数据(根据自己的数据结构,可自行选择添加)
interceptors.add(AdapterInterceptor());
configDio(
baseUrl: 'https://api.github.com/',
interceptors: interceptors,
);
}
void initQuickActions() {
if (Device.isMobile) {
const QuickActions quickActions = QuickActions();
if (Device.isIOS) {
// Android每次是重新启动activity,所以放在了splash_page处理。
// 总体来说使用不方便,这种动态的方式在安卓中局限性高。这里仅做练习使用。
quickActions.initialize((String shortcutType) async {
// if (shortcutType == 'demo') {
// navigatorKey.currentState?.push<dynamic>(MaterialPageRoute<dynamic>(
// builder: (BuildContext context) => const DemoPage(),
// ));
// }
});
}
quickActions.setShortcutItems(<ShortcutItem>[
const ShortcutItem(
type: 'demo',
localizedTitle: 'Demo',
icon: 'flutter_dash_black'
),
]);
}
}
@override
Widget build(BuildContext context) {
final Widget app = MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ThemeProvider()),
ChangeNotifierProvider(create: (_) => LocaleProvider())
],
child: Consumer2<ThemeProvider, LocaleProvider>(
builder: (_, ThemeProvider provider, LocaleProvider localeProvider, __) {
return _buildMaterialApp(provider, localeProvider);
},
),
);
/// Toast 配置
return OKToast(
backgroundColor: Colors.black54,
textPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0),
radius: 20.0,
position: ToastPosition.bottom,
child: app
);
}
Widget _buildMaterialApp(ThemeProvider provider, LocaleProvider localeProvider) {
return MaterialApp(
title: 'Flutter Deer',
// showPerformanceOverlay: true, //显示性能标签
// debugShowCheckedModeBanner: false, // 去除右上角debug的标签
// checkerboardRasterCacheImages: true,
// showSemanticsDebugger: true, // 显示语义视图
// checkerboardOffscreenLayers: true, // 检查离屏渲染
theme: theme ?? provider.getTheme(),
darkTheme: provider.getTheme(isDarkMode: true),
themeMode: provider.getThemeMode(),
home: home ?? const SplashPage(),
onGenerateRoute: Routes.router.generator,
localizationsDelegates: OnePoemLocalizations.localizationsDelegates,
supportedLocales: OnePoemLocalizations.supportedLocales,
locale: localeProvider.locale,
navigatorKey: navigatorKey,
builder: (BuildContext context, Widget? child) {
/// 仅针对安卓
if (Device.isAndroid) {
/// 切换深色模式会触发此方法,这里设置导航栏颜色
ThemeUtils.setSystemNavigationBar(provider.getThemeMode());
}
/// 保证文字大小不受手机系统设置影响 https://www.kikt.top/posts/flutter/layout/dynamic-text/
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: child!,
);
},
/// 因为使用了fluro,这里设置主要针对Web
onUnknownRoute: (_) {
return MaterialPageRoute<void>(
builder: (BuildContext context) => const NotFoundPage(),
);
},
restorationScopeId: 'app',
);
}
}