在 AI 辅助开发逐渐成为日常的今天,一套脚手架不仅要减少重复工作,也要让 AI 看懂项目结构、遵循开发规范,并在明确的架构边界内完成开发。
此前已经分享过鸿蒙和安卓版本的快速开发框架,这次继续带来 Flutter 版本。FlutterKit 基于 Flutter + Dart + GetX + TDesign Flutter,内置网络、分页、数据库、状态管理、导航、屏幕适配等常用能力,支持深色模式、国际化和多端适配,欢迎一起学习交流。
项目同时提供项目级 AGENTS.md 和覆盖 UI、数据、导航、主题、预览等场景的专项 Skill,帮助 AI 参与功能开发、代码重构、单元测试和文档维护。
项目亮点
- 开箱即用:内置网络、分页、数据库、状态管理等基础能力,无需重复搭建
- 完整示例:每个功能模块都提供可运行的 Demo 页面,方便直接查看效果和代码
- 质量保障:Core 与 Demo 均配套单元测试,行覆盖率不低于 98%,分支覆盖率不低于 95%
- 模块化架构:使用 bootstrap、core、routes、feature 划分职责,业务模块之间保持隔离
- 现代化技术栈:Flutter + Dart + GetX + TDesign Flutter,支持 Android、iOS、Web 和桌面端
- 屏幕适配:支持手机、折叠屏、平板以及横竖屏布局切换
- 深色模式:支持浅色、深色和跟随系统,并持久化用户选择
- 国际化支持:内置中英文语言切换,Core 与 Feature 文案分模块维护
- 在线文档:框架文档与代码同步维护,方便学习、查阅和二次开发
- AI 辅助开发:提供项目级
AGENTS.md和专项 Skill,帮助 AI 工具理解框架边界
如果项目对你有帮助,请给个 Star 支持 ⭐ 这对我来说很重要,能给我带来长期更新维护的动力!
项目地址:GitHub | Gitee
在线文档:flutter.dusksnow.top
Demo 下载:www.pgyer.com/FlutterKit
项目预览
💡 说明:框架提供了多种示例页面,展示网络、分页、数据库、主题、导航、状态管理等能力,支持手机、折叠屏和平板等设备形态。
📱 手机
📱 平板
架构设计
FlutterKit 采用模块化分层架构,从上到下分为业务层、核心层和入口层:
业务层(Feature)
- 功能模块:按业务域拆分,目前包含认证、用户、主页和 Demo 等模块
- 页面分层:使用 View + Logic + State + Binding 组织页面代码
- 模块组件:单模块复用的 Widget、数据和服务保留在 Feature 内
- 国际化资源:每个 Feature 单独维护文案 Key 和中英文翻译
核心层(Core)
- base:基础父类与页面状态封装(BaseLogic、BaseNetworkLogic、BaseListLogic、BaseRefreshLogic、BaseTabLogic)
- data:统一数据入口,保存 Repository 与静态 Preview Data
- database:基于 sqflite 的本地数据库能力
- datastore:基于 shared_preferences 的轻量级本地存储
- design_system:主题、颜色、间距、字体、形状、阴影和 Widget 链式扩展
- localization:Core 公共文案与翻译聚合
- model:请求模型、响应模型、分页模型和业务实体
- network:Dio、Retrofit、拦截器、DataSource 和 Debug 网络面板
- result:RequestHelper、统一错误格式化和请求结果处理
- service:用户状态、登录状态和跨页面共享 Service
- ui:通用 UI 组件、响应式断点和 Widget Preview
- util:Storage、Route、Toast、Alert、Size、Common 等工具
入口层(Application)
- 应用入口:负责 Flutter 应用启动与
GetMaterialApp构建 - 启动初始化:统一初始化存储、主题、语言、Service 和网络调试工具
- 路由注册:汇总各模块 GetPage、Binding、参数、结果和路由守卫
- 多端配置:维护 Android、iOS、Web、macOS、Linux、Windows 原生工程
依赖关系
- feature 依赖 core:业务模块可以使用 Core 提供的公共能力
- feature 不直接依赖 network / database:业务模块通过 Repository 访问底层数据
- routes 负责模块跳转:Feature 之间不直接 import 对方的页面实现
- core 不依赖 feature:公共能力不能反向引用具体业务模块
技术栈
| 类别 | 技术选型 | 说明 |
|---|---|---|
| 编程语言 | Dart | Flutter 官方开发语言 |
| UI 框架 | Flutter + TDesign Flutter | 跨平台 UI 与业务组件 |
| 架构模式 | View + Logic + State + Binding | 页面分层与依赖注册 |
| 状态与导航 | GetX | Rx、Obx、GetPage、Binding、Service |
| 网络请求 | Dio + Retrofit | HTTP 客户端、拦截器和接口声明 |
| 数据存储 | sqflite + shared_preferences | 数据库与轻量级本地存储 |
| 屏幕适配 | flutter_screenutil + BreakpointType | 尺寸适配与响应式断点 |
核心能力
1. 网络请求封装
基于 Dio + Retrofit 的网络请求封装,采用 DataSource → Repository → Logic 三层架构,框架统一处理错误、loading、toast、dialog 和页面状态。
功能特性:
- 统一管理 Dio 实例、baseUrl、timeout 和 headers
- 使用 Retrofit 声明类型安全的网络 DataSource
- 自动处理 HTTP 状态码与业务错误码
- 支持 RequestHelper 链式配置 loading、toast、dialog 和错误回调
- 支持 BaseNetwork 自动管理加载、错误、空数据和成功状态
- Debug 模式提供 Alice 网络请求面板和 PrettyDioLogger 日志
使用案例:
/// 请求商品详情。
Future<void> requestGoodsDetail() {
return RequestHelper.repository<Goods>(
GoodsRepository().getGoodsInfo(1),
)
.loading(true) // 请求过程显示 Loading。
.toast(true) // 业务失败自动显示 Toast。
.execute()
.then<void>((Goods? goods) {
LogUtil.d('商品详情:${goods?.title}');
})
.catchError((Object error) {
LogUtil.e(error.toString());
});
}
单次请求场景(自动处理加载、错误、空数据和成功状态):
/// 网络请求示例页 State。
class NetworkDemoState extends BaseNetworkState {
/// 商品详情。
final Rx<Goods> goods = Goods().obs;
}
/// 网络请求示例页 Logic。
class NetworkDemoLogic extends BaseNetworkLogic<Goods> {
/// 页面展示状态。
final NetworkDemoState networkDemoState = NetworkDemoState();
/// 商品仓库。
final GoodsRepository _goodsRepository = GoodsRepository();
/// 网络父类复用页面声明的 State。
@override
NetworkDemoState get networkState => networkDemoState;
/// 商品详情请求。
@override
Future<BaseResponse<Goods>> Function()? get apiRequest =>
() => _goodsRepository.getGoodsInfo(1);
/// 保存商品详情。
@override
void requestOk(Goods data) => networkDemoState.goods.value = data;
}
/// 网络请求示例页。
class NetworkDemoView extends BaseNetworkView<NetworkDemoLogic> {
/// 创建网络请求示例页。
NetworkDemoView({super.key, super.logic});
/// 构建请求成功后的页面内容。
@override
Widget bodyContent(NetworkDemoLogic logic) {
return Obx(
() => GoodsDetailContent(
goods: logic.networkDemoState.goods.value,
),
);
}
}
BaseNetworkLogic 会调用 apiRequest,请求成功后执行 requestOk();BaseNetworkView 根据当前状态展示 Loading、错误页、空页面或业务内容。
2. 分页列表封装
统一封装分页列表的首次加载、下拉刷新、上拉加载、空态、错误处理和无更多数据,开发者只需关心请求参数与列表项渲染。
功能特性:
- 自动处理加载中、成功、失败和空数据四种状态
- 自动处理下拉刷新与上拉加载更多
- 自动管理
currentPage、pageSize和分页请求参数 - 自动判断是否还有更多数据
- 加载更多失败后自动恢复到上一成功页
- 下一页返回空列表时保留已有内容并标记无更多数据
- 支持自定义加载、错误、空态和列表项 Widget
Logic 实现:
/// 网络列表示例页 State。
class NetworkListDemoState extends BaseListState<Goods> {
/// 单页商品数量。
@override
int get pageSize => 15;
}
/// 网络列表示例页 Logic。
class NetworkListDemoLogic extends BaseListLogic<Goods> {
/// 创建网络列表示例页 Logic。
///
/// [goodsRepository] 可选商品仓库,测试和预览可注入 Fake 实现。
NetworkListDemoLogic({GoodsRepository? goodsRepository})
: _goodsRepository = goodsRepository ?? GoodsRepository();
/// 页面分页状态。
final NetworkListDemoState networkListDemoState = NetworkListDemoState();
/// 分页父类复用页面声明的 State。
@override
NetworkListDemoState get listState => networkListDemoState;
/// 商品仓库。
final GoodsRepository _goodsRepository;
/// 商品分页请求。
@override
Future<BaseResponse<BaseListResponse<Goods>>> Function()? get apiRequest {
return () => _goodsRepository.getGoodsPage(
GoodsSearchRequest(
page: listState.currentPage,
size: listState.pageSize,
),
);
}
}
页面使用:
/// 网络列表示例页。
class NetworkListDemoView
extends BaseListView<NetworkListDemoLogic, Goods> {
/// 创建网络列表示例页。
NetworkListDemoView({super.key, super.logic});
/// 构建商品列表项。
///
/// [item] 当前商品。
/// [index] 当前索引。
@override
Widget itemWidget(Goods item, int index) {
return GoodsListCard(goods: item);
}
}
使用步骤:
- State 继承
BaseListState<T>,按需重写pageSize - Logic 继承
BaseListLogic<T>并实现apiRequest - View 继承
BaseListView<Logic, T>并实现itemWidget - 父类统一管理 EasyRefresh、页码、列表状态和无更多数据
具体实现代码,请参考:分页列表文档
3. 状态管理
基于 GetX 的 Rx、Obx 和 GetxService 实现页面状态与全局状态共享。
功能特性:
- 类型安全的响应式状态定义
Obx自动监听 Rx 变化并更新 Widget- 页面状态由 Feature State 管理
- 跨页面状态使用 GetxService 管理
- 主题、语言和用户状态支持持久化恢复
- Binding 统一注册页面 Logic,避免在 View 中创建控制器
状态定义:
/// Demo 计数器服务。
class DemoCounterService extends GetxService {
/// 当前计数值。
final RxInt count = 0.obs;
/// 计数值加一。
void increase() {
count.value += 1;
}
}
使用案例:
/// 构建状态管理示例。
Widget buildCounter() {
final DemoCounterService service = Get.find<DemoCounterService>();
return Obx(() {
return Column(
children: <Widget>[
TDText('当前计数:${service.count.value}'),
TDButton(text: '增加', onTap: service.increase),
],
);
});
}
页面临时状态放在 State,跨页面状态放在 Service,主题和语言等应用级状态放在 Application。不建议把所有 Rx 都放进全局 Service。
具体实现代码,请参考:状态管理文档
4. 导航管理
统一管理路由注册、页面跳转、参数传递、结果回传和登录拦截。
功能特性:
- 类型安全的路由参数与返回结果
- 模块化路由注册(Routes + Pages)
- 统一模块 Navigator
- 支持带参跳转与结果回传
- 支持登录拦截与 GetMiddleware 路由守卫
- Android 使用平台原生转场并支持预测性返回
路由定义:
/// Demo 模块路由。
abstract final class DemoRoutes {
static const String navigationWithArgs = '/demo/navigation-with-args';
static const String navigationResult = '/demo/navigation-result';
}
/// Demo 模块导航参数。
class DemoParams {
const DemoParams({required this.goodsId});
final int goodsId;
}
/// Demo 模块导航结果。
class DemoResult {
const DemoResult({required this.id, required this.message});
final int id;
final String message;
}
Navigator 封装(推荐):
/// Demo 模块导航器。
abstract final class DemoNavigator {
/// 跳转到带参导航示例页。
static Future<T?>? toNavigationWithArgs<T>(int goodsId) {
return toPage<T>(
DemoRoutes.navigationWithArgs,
arguments: DemoParams(goodsId: goodsId),
);
}
/// 跳转到结果回传示例页。
static Future<DemoResult?>? toNavigationResult() {
return toPage<DemoResult>(DemoRoutes.navigationResult);
}
}
使用案例:
/// 打开带参页面。
Future<void> openGoodsPage() async {
await DemoNavigator.toNavigationWithArgs<void>(10086);
}
/// 打开结果回传页面。
Future<void> openResultPage() async {
final DemoResult? result = await DemoNavigator.toNavigationResult();
if (result != null) {
ToastUtil.success(result.message);
}
}
/// 读取当前页面参数。
class NavigationWithArgsLogic extends BaseLogic {
late final DemoParams params = args as DemoParams;
}
/// 返回页面结果。
void submitResult() {
back<DemoResult>(const DemoResult(id: 1, message: '操作成功'));
}
应用根节点使用 Transition.native,Android Manifest 显式开启 android:enableOnBackInvokedCallback="true",让 Android 14 及以上页面接入预测性返回。
具体实现代码,请参考:导航管理文档
5. 屏幕适配
完整的屏幕适配方案,支持手机、折叠屏、平板以及横竖屏布局。
功能特性:
- XS / SM / MD / LG 四档响应式断点
BuildContext.bp()响应式取值BreakpointType.bp()支持 LayoutBuilder 局部约束- flutter_screenutil 提供基础尺寸适配
- SafeArea 与 MediaQuery 处理刘海、挖孔和手势区域
- 主页面根据横竖屏切换底部导航和左侧导航
- Widget Preview 同时检查多种设备尺寸
断点规则:
| 断点 | 说明 | 宽度范围(dp) |
|---|---|---|
XS | 超小屏 | < 320 |
SM | 小屏 | 320 - 599 |
MD | 中屏 | 600 - 839 |
LG | 大屏 | >= 840 |
网格布局适配:
/// 构建响应式商品网格。
Widget buildGoodsGrid(BuildContext context, List<Goods> goods) {
final int columns = context.bp<int>(xs: 2, sm: 2, md: 3, lg: 4);
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: columns,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
itemCount: goods.length,
itemBuilder: (BuildContext context, int index) {
return GoodsListCard(goods: goods[index]);
},
);
}
文本适配:
/// 构建响应式文本。
Widget buildAdaptiveText(BuildContext context) {
final double fontSize = context.bp<double>(
xs: 14,
sm: 14,
md: 16,
lg: 22,
);
return Text(
'大屏适配示例文字',
style: TextStyle(fontSize: fontSize),
);
}
导航栏位置调整:
/// 根据屏幕方向切换导航位置。
Widget buildMainLayout(
BuildContext context,
Widget page,
Widget sideNavigation,
) {
final bool isLandscape =
MediaQuery.orientationOf(context) == Orientation.landscape;
if (isLandscape) {
return Row(
children: <Widget>[
sideNavigation,
Expanded(child: page),
],
);
}
return page;
}
安全区适配:
普通页面顶部通过 BaseView.head() 的 AppBar 避开状态栏;底部操作区使用 SafeArea(top: false) 避开系统手势区域。
/// 构建页面底部操作按钮。
///
/// [onSubmit] 提交回调。
Widget buildBottomAction(VoidCallback onSubmit) {
return SafeArea(
top: false,
child: TDButton(text: '提交', onTap: onSubmit),
);
}
6. 数据库封装
基于 sqflite 的本地数据库能力,采用 DataSource → Repository 架构,业务层通过 Repository 访问数据库。
实体定义(简化示例):
/// Demo 表实体。
class DemoEntity {
const DemoEntity({
this.id,
this.title = '',
this.description,
});
final int? id;
final String title;
final String? description;
/// 转换为数据库字段 Map。
Map<String, dynamic> toMap({bool includeId = true}) {
return <String, dynamic>{
if (includeId) 'id': id,
'title': title,
'description': description,
};
}
}
使用案例:
/// 数据库示例页 Logic。
class DatabaseDemoLogic extends BaseLogic {
/// Demo 数据仓库。
final DemoRepository _demoRepository = DemoRepository();
/// Demo 记录列表。
final RxList<DemoEntity> items = <DemoEntity>[].obs;
/// 保存记录。
Future<void> save() async {
await _demoRepository.createDemo('示例标题', description: '示例描述');
items.value = await _demoRepository.getAll();
}
}
DatabaseProvider 统一管理数据库连接、并发首次打开、建表和关闭。DataSource 负责 SQL、表名和字段映射,Feature 不直接持有 Database。
具体实现代码,请参考:数据库文档
7. 本地存储
基于 shared_preferences 的轻量级本地存储,采用 DataSource → Repository 架构,业务层通过 Repository 访问 Token、主题、语言和用户缓存。
使用案例:
/// 本地存储示例页 Logic。
class LocalStorageDemoLogic extends BaseLogic {
/// 用户信息存储仓库。
final UserInfoStoreRepository _userInfoStoreRepository =
UserInfoStoreRepository();
/// 当前用户信息。
final Rxn<User> user = Rxn<User>();
/// 保存用户信息。
Future<void> saveUser() async {
const User demoUser = User(
id: 10086,
nickName: '演示用户',
phone: '18800000000',
);
await _userInfoStoreRepository.saveUserInfo(demoUser);
user.value = await _userInfoStoreRepository.getUserInfo();
}
/// 清除用户信息。
Future<void> clearUser() async {
await _userInfoStoreRepository.clearUserInfo();
user.value = null;
}
}
存储 Key、默认值和 JSON 转换都留在 DataSource 实现中。损坏的用户 JSON 会按无缓存处理,不会把解析异常直接抛给页面。
具体实现代码,请参考:本地存储文档
工具类
框架内置了常用工具,避免业务层重复实现:
- ToastUtil:普通、成功、警告和错误 Toast
- AlertUtil:确认、反馈和业务提示对话框
- RouteUtil:页面跳转、返回、参数读取和导航栈处理
- StorageUtil:SharedPreferences 基础读写
- CommonUtil:复制、震动、平台判断和通用判断
具体使用方法,请参考:工具类文档
项目结构
FlutterKit/
├── android / ios / web / ... # 六端原生工程
├── assets/ # 图片、图标、主题 JSON 和生成源图
├── docs/ # FlutterKit 与 TDesign 本地文档
├── lib/
│ ├── bootstrap/ # 启动初始化器
│ ├── core/ # 核心模块
│ │ ├── base/ # 基础父类
│ │ ├── data/ # Repository 与 Preview Data
│ │ ├── database/ # 数据库
│ │ ├── datastore/ # 本地存储
│ │ ├── design_system/ # 设计系统与链式扩展
│ │ ├── model/ # 数据模型
│ │ ├── network/ # 网络层
│ │ ├── result/ # 结果处理
│ │ ├── service/ # 全局 Service
│ │ └── ui / util / ... # UI、响应式和工具类
│ ├── feature/ # 功能模块
│ │ ├── auth/ # 认证模块
│ │ ├── demo/ # 示例模块
│ │ ├── main/ # 主模块
│ │ └── user/ # 用户模块
│ ├── routes/ # 路由、参数、结果和守卫
│ ├── application.dart # 初始化编排与应用级状态
│ └── main.dart # Flutter 应用入口
├── test/ # 单元测试与 Widget 测试
└── tool/ # 覆盖率检查等脚本
相关资源:
- 在线文档:flutter.dusksnow.top
- TDesign Flutter:tdesign.tencent.com/flutter/get…
- Demo 下载:www.pgyer.com/FlutterKit
- DeepWiki:deepwiki.com/Joker-x-dev…
如果这个项目对你有帮助,请给个 ⭐ Star 支持!
- GitHub:github.com/Joker-x-dev…
- Gitee:gitee.com/Joker-x-dev…