flutter 依赖
flutter 依赖
Section titled “flutter 依赖”-
网络请求:dio
-
responsive_framework
- 设置响应式布局
-
riverpod- 用途:将你带有
@riverpod注解的函数或类,转化为 UI 可用的fetchUserProvider或counterProvider。 - 不运行后果:你写的
extends _$Counter会持续报错,且 UI 无法找到对应的 Provider。
- 用途:将你带有
-
freezed- 用途:生成不可变对象。它会自动帮你写好
copyWith、==和hashCode(这是实现你最开始要求的 Set 集合存放对象自动去重 的核心逻辑)。 - 不运行后果:无法使用复杂的模型类。
- 用途:生成不可变对象。它会自动帮你写好
-
json_serializable- 用途:生成
fromJSON和toJSON的具体实现代码。 - 不运行后果:无法自动将后端返回的 Map 数据转换为 Dart 对象。
- 用途:生成
-
资源与路由优化(推荐生成)
这些库虽然可选,但在 2026 年的规范项目中通常都会使用:
flutter_gen_runner- 用途:将你的图片(Assets)和字体自动转化为代码变量。
- 效果:你可以写
Assets.images.logo.path而不是手动打字符串"assets/logo.png"。
go_router_builder- 用途:为 GoRouter 提供类型安全的路由跳转。
- 效果:避免手动写字符串路径,防止商城项目页面多了之后跳转出错。
- flutter_secure_storage : 安全存储
- shared_preferences:持久话kv存储
name: groe_app_paddescription: "A new Flutter project."publish_to: 'none' # Remove this line if you wish to publish to pub.devversion: 1.0.0+1environment: sdk: ^3.9.2dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter cupertino_icons: ^1.0.8 collection: ^1.19.1 dio: ^5.9.2 flutter_riverpod: ^3.0.0 go_router: ^17.1.0 responsive_framework: ^1.5.1 flutter_secure_storage: ^10.0.0 webview_flutter: ^4.13.1 flutter_staggered_grid_view: ^0.7.0 mobile_scanner: ^7.2.0
intl: any shared_preferences: ^2.5.5dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 flutter_gen_runner: ^5.13.0+1 build_runner: ^2.9.0flutter: generate: true uses-material-design: true assets: - assets/images/ - assets/html/flutter_gen: output: lib/gen/ line_length: 100| 项 | 说明 |
|---|---|
| 名称 | groe_app_pad |
| SDK | ^3.9.2(Dart 3.9 及以上) |
| 发布 | publish_to: 'none' 表示不发布到 pub.dev,私有应用 |
dependencies(运行时依赖)
Section titled “dependencies(运行时依赖)”| 依赖 | 版本约束 | 作用简述 |
|---|---|---|
| flutter | SDK | Flutter 框架本体。 |
| flutter_localizations | SDK | 官方本地化(MaterialApp 的 localizationsDelegates 等),与 intl、ARB 生成代码配合做多语言。 |
| cupertino_icons | ^1.0.8 | iOS 风格图标字体,配合 CupertinoIcons 使用。 |
| collection | ^1.19.1 | 集合工具(如 groupBy、firstWhereOrNull 等),减少手写循环与空安全样板代码。 |
| dio | ^5.9.2 | HTTP 客户端:拦截器、超时、下载、FormData 等,适合对接 REST API(项目里建议与统一 Dio 实例、拦截器一起用)。 |
| flutter_riverpod | ^3.0.0 | 状态管理与依赖注入:Provider / Notifier 等,与 UI 解耦、可测试。 |
| go_router | ^17.1.0 | 声明式路由与深链接,替代手写 Navigator 栈管理,适合多页面/平板布局。 |
| responsive_framework | ^1.5.1 | 响应式断点、缩放或约束布局,让同一套 UI 在不同屏幕宽度下更易适配。 |
| flutter_secure_storage | ^10.0.0 | 安全存储(Keychain / Keystore 等),适合存 token、密钥等敏感数据,优于明文 SharedPreferences。 |
| webview_flutter | ^4.13.1 | 内嵌 WebView,用于展示 H5、活动页、文档等与 assets/html/ 本地页配合。 |
| flutter_staggered_grid_view | ^0.7.0 | 瀑布流/不规则网格(多列高度不一),适合图片墙、卡片瀑布布局。 |
| mobile_scanner | ^7.2.0 | 相机扫码(二维码/条码等),依赖平台相机权限与原生实现。 |
| intl | any | 日期/数字/消息格式化;flutter_localizations 与 gen-l10n 常会间接依赖它,any 表示由解析器选兼容版本(注意:生产环境若需可复现构建,可改为固定版本范围)。 |
| shared_preferences | ^2.5.5 | 轻量键值持久化(用户设置、非敏感标记等),数据存于平台偏好存储,不宜存高敏感信息。 |
dev_dependencies(仅开发/构建)
Section titled “dev_dependencies(仅开发/构建)”| 依赖 | 版本约束 | 作用简述 |
|---|---|---|
| flutter_test | SDK | 单元测试、Widget 测试、flutter test 所需。 |
| flutter_lints | ^5.0.0 | 官方推荐 lint 集合,配合 analysis_options.yaml 统一代码风格与静态检查。 |
| build_runner | ^2.9.0 | 运行代码生成任务的总入口(监听模式 watch、一次性 build)。 |
| flutter_gen_runner | ^5.13.0+1 | 根据 pubspec 的 flutter.assets 等生成类型安全的资源访问代码(与下方 flutter_gen 配置对应)。 |
flutter 与 flutter_gen(与依赖相关的配置)
Section titled “flutter 与 flutter_gen(与依赖相关的配置)”| 配置 | 作用 |
|---|---|
| generate: true | 启用 Flutter 内置生成器(例如 gen-l10n,从 l10n.yaml + ARB 生成 app_localizations*.dart)。 |
| uses-material-design: true | 打包 Material 图标字体。 |
| assets | assets/images/、assets/html/ 声明给打包与(可选)flutter_gen 扫描。 |
| flutter_gen.output: lib/gen/ | 将 flutter_gen 生成的资源 Dart 代码输出到 lib/gen/,避免手写字符串路径。 |
| flutter_gen.line_length: 100 | 生成代码换行宽度,与团队格式化习惯对齐。 |
使用上的简短建议
Section titled “使用上的简短建议”intl: any:能少操心版本冲突,但 CI 可重复性略差;若团队介意,可改为例如intl: ^0.20.2(以当前 Flutter 解析结果为准)。- 敏感数据:token 等优先 flutter_secure_storage;一般配置用 shared_preferences。
- 网络:业务层用 dio,路由用 go_router,全局状态用 flutter_riverpod,与你们架构规则里的分层一致即可。
如果你希望这份内容落盘成仓库里的 docs/DEPENDENCIES.md,可以说一下目标路径,我可以按你仓库习惯写好一版文件内容(你本地保存或让我改仓库都行)。
flutter响应式lib
Section titled “flutter响应式lib”| 响应式框架 | responsive_framework | 自动处理断点,支持 UI 等比缩放或重排。 |
|---|---|---|
| 自适应导航 | flutter_adaptive_scaffold | 官方出品,快速实现手机/平板/桌面三端导航切换。 |
方案
| 维度 | flutter_screenutil (比例缩放派) | responsive_framework (自适应布局派) |
|---|---|---|
| 核心逻辑 | 等比拉伸/缩小。所有组件随屏幕尺寸变大而变大,变小而变小。 | 布局重组/断点控制。小屏堆叠、大屏分栏或自动扩充内容。 |
| 代码习惯 | 必须在每个宽高、字号后加 .w, .h, .sp。 | 直接写数字,在全局或局部配置断点行为。 |
| Pad 表现 | 像一个“巨型手机版”。按钮和文字会变得很大。 | 像“专业 Pad 版”。按钮大小不变,但显示的商品列数和内容变多。 |
| 2026 年地位 | 属于UI 适配工具。 | 属于布局架构工具。 |
1. responsive_framework配置
Section titled “1. responsive_framework配置”等比缩放和设置断点
// iPad/桌面保持固定最大宽度,小屏按 1024 设计稿等比缩放。 final content = ResponsiveBreakpoints.builder( child: Builder( builder: (context) { final enableScale = !context.isTabletUp; return MaxWidthBox( maxWidth: 1400, child: ClipRect( child: ResponsiveScaledBox( // < 600:按 1024 基准做等比缩放(开启) // >= 600:不做全局等比缩放(关闭) width: enableScale ? 1024 : null, child: DismissKeyboardOnTap( child: child ?? const SizedBox.shrink(), ), ), ), ); }, ), breakpoints: const [ /// 设下不同设备的断点 Breakpoint(start: 0, end: 599, name: MOBILE), Breakpoint(start: 750, end: 1023, name: TABLET), Breakpoint(start: 1024, end: 3000, name: DESKTOP), ], );- 设置扩展
import 'package:flutter/material.dart';import 'package:groe_app_pad/l10n/app_localizations.dart';import 'package:responsive_framework/responsive_framework.dart';
extension BuildContextX on BuildContext { bool get isTabletUp => ResponsiveBreakpoints.of(this).largerOrEqualTo(TABLET); AppLocalizations get l10n => AppLocalizations.of(this)!;}
// 使用 @override Widget build(BuildContext context) { final isTabletUp = context.isTabletUp; // 当然也可以直接这样使用 final isTablet = ResponsiveBreakpoints.of(context).isTablet; }2. MaxWidthBox (最大宽度锁定) —— 解决 2080px 散架问题
Section titled “2. MaxWidthBox (最大宽度锁定) —— 解决 2080px 散架问题”当你锁定基准宽度为 600dp,但在 2080px 的超宽屏(如 4K 屏)上运行时,即使有缩放,UI 也会因为拉伸过宽而显得很怪。
-
功能:强制给内容设置一个最大边界,超出部分留白或填充背景。
-
用法:
dart
MaxWidthBox(maxWidth: 1200, // 无论屏幕多宽,主体内容最宽只展示 1200dpbackground: Container(color: Colors.grey[200]), // 左右两侧留白背景child: child!,)
MaterialApp( builder: (context, child) => ResponsiveBreakpoints.builder( // 1. 最外层:锁定最大宽度,防止 2080px 这种超宽屏导致 UI 散架 child: MaxWidthBox( maxWidth: 1200, // 无论屏幕多宽,商城内容区最大 1200dp background: Container(color: const Color(0xFFF5F5F5)), // 屏幕两侧多出的部分背景色 // 2. 中间层:执行镜像缩放,让你不用写 .w child: ResponsiveScaledBox( width: 600, // 你的设计稿基准宽度 child: child!, // 这里是具体的页面内容 ), ), // 3. 断点配置:用于代码里判断 isTablet breakpoints: [ const Breakpoint(start: 0, end: 450, name: MOBILE), const Breakpoint(start: 451, end: 1200, name: TABLET), const Breakpoint(start: 1201, end: double.infinity, name: DESKTOP), ],),home: const HomeScreen(),);3. ResponsiveRowColumn (行列自动转换)
Section titled “3. ResponsiveRowColumn (行列自动转换)”这是针对商城 App 详情页的神器。它可以根据断点自动切换 横向 (Row) 或 纵向 (Column) 排列。
-
场景:手机上是“上图下文”,Pad 上自动变成“左图右文”。
-
优势:不需要写两个 Widget,只需包裹一层。
-
写法:
dart
ResponsiveRowColumn(// 核心逻辑:手机返回 COLUMN,Pad 返回 ROWlayout: ResponsiveBreakpoints.of(context).isMobile? ResponsiveRowColumnType.COLUMN: ResponsiveRowColumnType.ROW,// 间距设置:Row 时水平间距 20,Column 时垂直间距 20columnSpacing: 20,rowSpacing: 20,// 决定这里横着排还是竖着排children: [// 左侧/上侧:商品大图ResponsiveRowColumnItem(rowFlex: 2, // 在 Pad 上占 2 份宽度child: Image.asset('assets/product.png', fit: BoxFit.cover),),// 右侧/下侧:商品标题和价格ResponsiveRowColumnItem(rowFlex: 3, // 在 Pad 上占 3 份宽度child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [Text("2026 新款超轻跑步鞋", style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),SizedBox(height: 10),Text("¥599.00", style: TextStyle(color: Colors.red, fontSize: 20)),],),),],)
4. ResponsiveGridView (响应式网格)
Section titled “4. ResponsiveGridView (响应式网格)”它增强了原生的 GridView,让你可以针对不同断点直接配置间距和对齐方式。
- 功能:在不同设备上自动调整固定间距和自适应列数,配合
ScaledBox使用时,能产生极其稳定的宫格效果。 - 2026 年的高级进阶:Banned/Clamping (缩放限制)
在全局缩放模式下,如果你担心在某些极小或极大的屏幕上缩放得太离谱:
- 功能:可以设置缩放的“上下限”。
- 作用:比如设置最小缩放不低于 0.8 倍,最大不超过 1.5 倍,防止 UI 元素在 2080px 屏幕上大到像桌面图标。
import 'package:flutter/material.dart';import 'package:flutter_riverpod/flutter_riverpod.dart';import 'package:responsive_framework/responsive_framework.dart';import '../providers/home_controller.dart'; // 引入你的控制器
class HomeProductGrid extends ConsumerWidget { const HomeProductGrid({super.key});
@override Widget build(BuildContext context, WidgetRef ref) { // 1. 获取 Controller 中的商品数据状态 final productState = ref.watch(homeControllerProvider);
// 2. 根据状态渲染 UI return productState.when( data: (products) => ResponsiveGridView.builder( // 这里就是你写的那个组件 gridDelegate: const ResponsiveGridDelegate( maxExtent: 200, mainAxisSpacing: 16, crossAxisSpacing: 16, childAspectRatio: 0.8, ), itemCount: products.length, padding: const EdgeInsets.all(16), itemBuilder: (context, index) { final product = products[index]; return ProductCard(product: product); // 渲染单个商品卡片 }, ), loading: () => const Center(child: CircularProgressIndicator()), error: (err, stack) => Center(child: Text('加载失败: $err')), ); }}5. 旋转屏幕的原因
Section titled “5. 旋转屏幕的原因”原因就在这里,不是你错觉,我刚查了你那两个包的真实配置:
- 你的 uniapp 包:
targetSdk=28 - 你的 Flutter 包:
targetSdk=36
这会导致系统行为完全不同。
在 Android 16(API 36)+ 大屏设备(平板)上,系统会对 screenOrientation / setRequestedOrientation 做“自适配优先”处理,很多情况下不会按老规则强锁方向。
- 在大屏设备(你这个 Pixel Tablet 属于)上,系统会默认放宽/忽略方向限制
而 targetSdk=28 的旧应用还走老兼容路径,所以看起来“uniapp 能锁,Flutter 不能锁”。
一句话:不是 uniapp 天生更能锁,是它 targetSdk 更低,绕开了 Android 16 新规则。
你现在有两个可行方案:
- 临时稳定方案:把 Flutter 的
targetSdk降到35(你刚才也同意可考虑),旋转锁会恢复老行为 - 长期方案:按 Android 16 的大屏自适配规范改 UI,不再依赖强锁方向
如果你要,我下一步就直接把项目改成 targetSdk=35 并帮你重装验证。