| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:get/get.dart';
- import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
- import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
- import '../config/theme/ix_theme.dart';
- import '../config/translations/localization_service.dart';
- import '../config/translations/strings_enum.dart';
- import '../utils/developer/ix_developer_tools.dart';
- import '../utils/device_manager.dart';
- import '../utils/ix_back_button_dispatcher.dart';
- import 'components/ix_snackbar.dart';
- import 'constants/configs.dart';
- import 'data/sp/ix_sp.dart';
- import 'routes/app_pages.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'widgets/click_opacity.dart';
- import 'widgets/gradient_circle_header.dart';
- import 'widgets/triple_tap_detector.dart';
- class App extends StatelessWidget {
- const App({super.key});
- @override
- Widget build(BuildContext context) {
- return ScreenUtilInit(
- designSize: const Size(375, 812),
- minTextAdapt: true,
- splitScreenMode: true,
- useInheritedMediaQuery: true,
- // 只在屏幕尺寸真正变化时才重建(如旋转屏幕),而不是每次 MediaQuery 变化都重建
- rebuildFactor: (old, data) => old.size != data.size,
- builder: (context, widget) => RefreshConfiguration(
- headerBuilder: () =>
- GradientCircleHeader(), // 配置默认页眉指示器。如果您每个页面都有相同的页眉指示器,您需要设置此
- footerBuilder: () => ClassicFooter(), // 配置默认底部指示器
- headerTriggerDistance: 80.0, // 标题触发刷新触发距离
- springDescription: SpringDescription(
- mass: 1,
- stiffness: 1000,
- damping: 100,
- ), // 设置没有回弹动画,属性含义请参阅Flutter API
- maxOverScrollExtent: 40, //头部最大拖动范围。如果发生超出视图区域的情况,请设置此属性
- maxUnderScrollExtent: 0, // 底部最大拖动范围
- enableScrollWhenRefreshCompleted:
- true, //此属性与PageView和TabBarView不兼容。如果您需要TabBarView左右滑动,则需要将其设置为true。
- enableLoadingWhenFailed: true, //在负载失败的情况下,用户仍然可以通过手势下拉触发更多负载。
- hideFooterWhenNotFull: false, //禁用上拉加载更多功能,当视口小于一屏时
- enableBallisticLoad: true, //触发通过BallisticScrollActivity加载更多
- child: _buildMaterialApp(),
- ),
- );
- }
- Widget _buildMaterialApp() {
- return GetMaterialApp.router(
- title: 'ixVPN',
- useInheritedMediaQuery: true,
- debugShowCheckedModeBanner: Configs.debug,
- backButtonDispatcher: IXBackButtonDispatcher(),
- getPages: AppPages.routes,
- theme: IXTheme.getThemeData(isLight: true),
- darkTheme: IXTheme.getThemeData(isLight: false),
- themeMode: ReactiveTheme.initialThemeMode,
- fallbackLocale: LocalizationService.defaultLanguage,
- locale: IXSP.getCurrentLocal(),
- translations: LocalizationService.getInstance(),
- builder: (context, widget) => _buildThemedApp(context, widget),
- );
- }
- Widget _buildThemedApp(BuildContext context, Widget? widget) {
- return MediaQuery(
- data: MediaQuery.of(context).copyWith(textScaler: TextScaler.noScaling),
- child: Stack(
- children: [
- widget!,
- Positioned(
- top: 0,
- right: 0,
- width: 100,
- height: 100,
- child: TripleTapDetector(
- requiredTaps: 10,
- onTripleTap: () async {
- Clipboard.setData(
- ClipboardData(text: await DeviceManager.getDeviceId()),
- );
- IXSnackBar.showIXSnackBar(
- title: Strings.copied.tr,
- message: await DeviceManager.getDeviceId(),
- );
- },
- child: const SizedBox.shrink(), // 不显示任何东西
- ),
- ),
- if (Configs.debug)
- Positioned(
- bottom: 100,
- right: 10,
- child: ClickOpacity(
- child: Container(
- width: 40,
- height: 40,
- decoration: BoxDecoration(
- color: Get.reactiveTheme.primaryColor.withValues(
- alpha: 0.5,
- ),
- borderRadius: BorderRadius.circular(40),
- ),
- child: Icon(Icons.adb, color: Get.reactiveTheme.primaryColor),
- ),
- onTap: () {
- // 使用简化版开发者工具
- IXDeveloperTools.show();
- },
- ),
- ),
- ],
- ),
- );
- }
- }
|