Files
kidgo/app/lib/main.dart
T

67 lines
3.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 入口:安装全局错误钩子后用标准 runApp 启动。
// 关键点:release 包里框架/build 抛出的异常不会被自动展示,只会留黑屏;
// 这里统一接管 FlutterError.onError、Zone 未捕获异常与 ErrorWidget.builder。
// ensureInitialized 与 runApp 都放进同一个 zone,避免触发 debugCheckZone 的
// "Zone mismatch"。runApp 内部会做 wrapWithDefaultView,注入 View 祖先。
import 'dart:async' show runZonedGuarded;
import 'package:flutter/foundation.dart'
show FlutterErrorDetails, defaultTargetPlatform, TargetPlatform;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'
show DeviceOrientation, SystemChrome, SystemUiMode;
import 'package:iwbtc/src/core/app_error.dart';
import 'package:iwbtc/src/app_root.dart' show AppRoot;
Future<void> main() async {
runZonedGuarded(
() async {
WidgetsFlutterBinding.ensureInitialized();
// 框架级错误(build / layout / paint / 手势回调等)。
FlutterError.onError = (FlutterErrorDetails d) {
FlutterError.presentError(d); // 保持控制台/日志里的完整输出
AppError.reportFlutter(d);
};
// Widget 抛错时的占位界面 —— 换成可读文案,而不是默认的红屏/黑屏。
ErrorWidget.builder = (FlutterErrorDetails d) =>
AppError.buildScreen(d.exceptionAsString());
await _configureMobile();
runApp(const AppRoot());
},
(Object e, StackTrace st) {
AppError.reportZone(e, st);
},
);
}
/// 移动端专属的显示适配:横屏锁定 + 沉浸式全屏。
///
/// 画面是 800×608 的横向虚拟舞台,横屏下信箱缩放才能拿到可用的可视比例;
/// 竖屏时上下留白巨大、画面极小,虚拟手柄也会挤成一团。桌面端保持原样不干预。
/// (安卓另有 AndroidManifest 的 `screenOrientation="sensorLandscape"`,
/// 保证冷启动第一帧就是横屏,避免先竖后横的闪烁。)
///
/// 沉浸式:用 `SystemUiMode.immersiveSticky` 隐藏状态栏与导航栏,让游戏
/// 铺满整个屏幕,与常规手机游戏一致。相比普通 `immersive`,
/// `immersiveSticky` 在用户从屏幕边缘滑出系统栏后数秒会**自动重新隐藏**,
/// 不会弹出"退出沉浸模式"的提示条,体验更顺。
Future<void> _configureMobile() async {
final t = defaultTargetPlatform;
if (t != TargetPlatform.android && t != TargetPlatform.iOS) return;
try {
await SystemChrome.setPreferredOrientations(<DeviceOrientation>[
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
// 沉浸式全屏:隐藏状态栏与导航栏,游戏铺满整个屏幕。
await SystemChrome.setEnabledSystemUIMode(
SystemUiMode.immersiveSticky,
);
} catch (e) {
// 某些设备/系统策略不允许锁定方向或沉浸,属可容忍情况,不影响游戏运行。
AppError.warn('移动端显示适配失败(横屏/沉浸)', '$e');
}
}