main.dart 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import 'dart:io';
  2. import 'package:device_info_plus/device_info_plus.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/services.dart';
  5. import 'package:image_puzzle/app_lifecycle/app_lifecycle.dart';
  6. import 'package:image_puzzle/audio/audio_controller.dart';
  7. import 'package:image_puzzle/homepage/home_screen.dart';
  8. import 'package:image_puzzle/models/data.dart';
  9. import 'package:image_puzzle/models/items.dart';
  10. import 'package:image_puzzle/persistence/persistence.dart';
  11. import 'package:image_puzzle/play/board_play.dart';
  12. import 'package:image_puzzle/settings/settings_controller.dart';
  13. import 'package:logging/logging.dart';
  14. import 'dart:developer' as dev;
  15. import 'package:path_provider/path_provider.dart';
  16. import 'package:provider/provider.dart';
  17. import 'config/config.dart';
  18. import 'config/device.dart';
  19. Logger _log = Logger('main.dart');
  20. final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
  21. void main() async {
  22. // Subscribe to log messages.
  23. Logger.root.onRecord.listen((record) {
  24. dev.log(
  25. record.message,
  26. time: record.time,
  27. level: record.level.value,
  28. name: record.loggerName,
  29. zone: record.zone,
  30. error: record.error,
  31. stackTrace: record.stackTrace,
  32. );
  33. });
  34. WidgetsFlutterBinding.ensureInitialized();
  35. // 强制竖屏
  36. SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
  37. // 进入全屏沉浸式, 隐藏底部导航以及状态栏
  38. if (Platform.isAndroid) {
  39. SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
  40. }
  41. SystemChrome.setSystemUIOverlayStyle(
  42. const SystemUiOverlayStyle(
  43. statusBarColor: Colors.transparent, // <-- SEE HERE
  44. statusBarIconBrightness: Brightness.dark, //<-- For Android SEE HERE (dark icons)
  45. statusBarBrightness: Brightness.light, //<-- For iOS SEE HERE (dark icons)
  46. ),
  47. );
  48. //本地参数存储初始化
  49. await Persistence().initialize();
  50. // 程序首次运行时间
  51. DateTime firstRunTime = Persistence().firstRunTime;
  52. _log.info("first_run_time: $firstRunTime, now: ${DateTime.now()}");
  53. // 记录程序运行时间
  54. Persistence().lastRunTime = DateTime.now();
  55. Directory baseDir = await getApplicationDocumentsDirectory();
  56. runApp(MyApp(baseDir: baseDir));
  57. }
  58. class MyApp extends StatelessWidget {
  59. final Directory baseDir;
  60. const MyApp({super.key, required this.baseDir});
  61. // This widget is the root of your application.
  62. @override
  63. Widget build(BuildContext context) {
  64. Config config = Config(context, baseDir);
  65. return AppLifecycleObserver(
  66. child: MultiProvider(
  67. providers: [
  68. Provider<Data>(lazy: false, create: (context) => Data(persistence: Persistence())..loadDataFromPersistence()),
  69. Provider<SettingsController>(lazy: false, create: (context) => SettingsController(persistence: Persistence())..loadStateFromPersistence()),
  70. ProxyProvider2<SettingsController, ValueNotifier<AppLifecycleState>, AudioController>(
  71. // Ensures that the AudioController is created on startup,
  72. // and not "only when it's needed", as is default behavior.
  73. // This way, music starts immediately.
  74. lazy: false,
  75. create: (context) => AudioController()..initialize(),
  76. update: (context, settings, lifecycleNotifier, audio) {
  77. if (audio == null) throw ArgumentError.notNull();
  78. audio.attachSettings(settings);
  79. audio.attachLifecycleNotifier(lifecycleNotifier);
  80. return audio;
  81. },
  82. dispose: (context, audio) => audio.dispose(),
  83. ),
  84. Provider<Config>(lazy: false, create: (context) => config),
  85. Provider<Device>(lazy: false, create: (context) => config.device),
  86. ],
  87. child: Prepare(
  88. child: MaterialApp(
  89. key: GlobalKey(),
  90. title: 'Image Puzzle',
  91. initialRoute: '/',
  92. navigatorObservers: [routeObserver],
  93. routes: {
  94. '/': (context) => const HomeScreen(),
  95. '/play': (context) => BoardPlay(item: AssetItem('0', 2057, 2878, 4, true, 'assets/images/test.jpeg', 'assets/images/test.jpeg')),
  96. },
  97. theme: ThemeData(brightness: Brightness.light, primaryColor: Colors.green, primarySwatch: Colors.blue),
  98. ),
  99. ),
  100. ),
  101. );
  102. }
  103. }
  104. class Prepare extends StatefulWidget {
  105. final Widget child;
  106. const Prepare({super.key, required this.child});
  107. @override
  108. State<Prepare> createState() => _PrepareState();
  109. }
  110. class _PrepareState extends State<Prepare> {
  111. @override
  112. void initState() {
  113. super.initState();
  114. loadDeviceInfo();
  115. }
  116. /// 获取android平台信息,用户判断是否低端机
  117. loadDeviceInfo() async {
  118. DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
  119. if (Platform.isAndroid) {
  120. try {
  121. context.read<Device>().androidDeviceInfo = await deviceInfoPlugin.androidInfo;
  122. } catch (e) {}
  123. }
  124. }
  125. @override
  126. Widget build(BuildContext context) {
  127. //Update ad banner size
  128. // AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(
  129. // MediaQuery.of(context).size.width.truncate(),
  130. // ).then((value) {
  131. // if (value != null) {
  132. // context.read<Device>().bannerHeight = value.height.toDouble();
  133. // }
  134. // }).catchError((err) {
  135. // //todo
  136. // });
  137. context.read<Device>().bannerHeight = 50;
  138. return widget.child;
  139. }
  140. }