1.4 业务模块初始

1.4 业务模块初始

业务模块初始步骤


第 1 步: 业务模块规划

模块命名

一层 二层 说明
styles styles_index 样式首页
text 文本
icon 图标
image 图片
buttons 按钮
text_form 输入表单
inputs 输入框
group_list 分组列表
carousel 滚动图片
bottom_sheet 底部弹出框
components 业务组件
other 其它
system splash 首屏
welcome 欢迎
main 主界面
login 登录
register 注册
register_pin 注册 pin
user_agreement 用户协议
goods home 商品首页
product_list 商品列表
product_details 商品详情页
category 商品分类页
search search_index 搜索列表
search_filter 搜索筛选
my my_index 我的首页
profile_edit 编辑个人信息
order_list 订单列表
order_details 订单详情
my_address 地址编辑
language 多语言
theme 主题
cart cart_index 购物车
buy_now 立刻购买
buy_done 购买完成
apply_promo_code 使用优惠券

一般 pages 下分成 2 层就行,不要再深了,宁可做平行设计,也不要纵深太多。

第 2 步: main 主界面用 GetBuilder + StatefulWidget

主界面包含导航和 Tab 切换所以需要

右键菜单选 “Getx: StatefulWidget + GetBuilder Page”

其实就是 StatefulWidget 包裹了一个 GetBuilder,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'index.dart';

/// StatefulWidget 页面
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);

@override _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;

@override
Widget build(BuildContext context) {
super.build(context);
return const _MainViewGetX();
}
}

/// getx 组件
class _MainViewGetX extends GetView<MainController> {
const _MainViewGetX({Key? key}) : super(key: key);

Widget _buildView() {
return const Center(
child: Text("MainPage"),
);
}

@override
Widget build(BuildContext context) {
return GetBuilder<MainController>(
init: MainController(),
id: "main",
builder: (_) {
return Scaffold(
appBar: AppBar(title: const Text("main")),
body: SafeArea(
child: _buildView(),
),
);
},
);
}
}

这样的代码结构,层次比较清楚

第 3 步: 生成页面 路由命名、定义、导包

右键菜单选 “☆ Getx: Routers Generate”

所有的模块生成后,清单如下

lib/common/routers/names.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class RouteNames {
static const main = '/';

static const cartApplyPromoCode = '/cart_apply_promo_code';
static const cartBuyDone = '/cart_buy_done';
static const cartBuyNow = '/cart_buy_now';
static const cartCartIndex = '/cart_cart_index';
static const goodsCategory = '/goods_category';
static const goodsHome = '/goods_home';
static const goodsProductDetails = '/goods_product_details';
static const goodsProductList = '/goods_product_list';
static const myAddressEdit = '/my_address_edit';
static const myAddressList = '/my_address_list';
static const myLanguage = '/my_language';
static const myMyIndex = '/my_my_index';
static const myOrderDetails = '/my_order_details';
static const myOrderList = '/my_order_list';
static const myProfileEdit = '/my_profile_edit';
static const myTheme = '/my_theme';
static const searchSearchFilter = '/search_search_filter';
static const searchSearchIndex = '/search_search_index';
static const stylesBottomSheet = '/styles_bottom_sheet';
static const stylesButtons = '/styles_buttons';
static const stylesCarousel = '/styles_carousel';
static const stylesComponents = '/styles_components';
static const stylesGroupList = '/styles_group_list';
static const stylesInputs = '/styles_inputs';
static const stylesOther = '/styles_other';
static const stylesStylesIndex = '/styles_styles_index';
static const stylesText = '/styles_text';
static const stylesTextForm = '/styles_text_form';
static const stylesIcon = '/styles_icon';
static const stylesImage = '/styles_image';
static const systemLogin = '/system_login';
static const systemMain = '/system_main';
static const systemRegister = '/system_register';
static const systemRegisterPin = '/system_register_pin';
static const systemSplash = '/system_splash';
static const systemUserAgreement = '/system_user_agreement';
}

lib/common/routers/observers.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import 'package:flutter/material.dart';

import 'index.dart';

/// 记录路由的变化
class RouteObservers<R extends Route<dynamic>> extends RouteObserver<R> {
@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPush(route, previousRoute);
var name = route.settings.name ?? '';
if (name.isNotEmpty) RoutePages.history.add(name);
debugPrint('didPush');
debugPrint(RoutePages.history.toString());
}

@override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPop(route, previousRoute);
RoutePages.history.remove(route.settings.name);
debugPrint('didPop');
debugPrint(RoutePages.history.toString());
}

@override
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
if (newRoute != null) {
var index = RoutePages.history.indexWhere((element) {
return element == oldRoute?.settings.name;
});
var name = newRoute.settings.name ?? '';
if (name.isNotEmpty) {
if (index > 0) {
RoutePages.history[index] = name;
} else {
RoutePages.history.add(name);
}
}
}
debugPrint('didReplace');
debugPrint(RoutePages.history.toString());
}

@override
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didRemove(route, previousRoute);
RoutePages.history.remove(route.settings.name);
debugPrint('didRemove');
debugPrint(RoutePages.history.toString());
}

@override
void didStartUserGesture(
Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didStartUserGesture(route, previousRoute);
}

@override
void didStopUserGesture() {
super.didStopUserGesture();
}
}

lib/common/routers/pages.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../pages/index.dart';
import 'index.dart';

class RoutePages {
static final RouteObserver<Route> observer = RouteObservers();
static List<String> history = [];

static List<GetPage> list = [
GetPage(
name: RouteNames.cartApplyPromoCode,
page: () => const ApplyPromoCodePage(),
),
GetPage(
name: RouteNames.cartBuyDone,
page: () => const BuyDonePage(),
),
GetPage(
name: RouteNames.cartBuyNow,
page: () => const BuyNowPage(),
),
GetPage(
name: RouteNames.cartCartIndex,
page: () => const CartIndexPage(),
),
GetPage(
name: RouteNames.goodsCategory,
page: () => const CategoryPage(),
),
GetPage(
name: RouteNames.goodsHome,
page: () => const HomePage(),
),
GetPage(
name: RouteNames.goodsProductDetails,
page: () => const ProductDetailsPage(),
),
GetPage(
name: RouteNames.goodsProductList,
page: () => const ProductListPage(),
),
GetPage(
name: RouteNames.myAddressEdit,
page: () => const AddressEditPage(),
),
GetPage(
name: RouteNames.myAddressList,
page: () => const AddressListPage(),
),
GetPage(
name: RouteNames.myLanguage,
page: () => const LanguagePage(),
),
GetPage(
name: RouteNames.myMyIndex,
page: () => const MyIndexPage(),
),
GetPage(
name: RouteNames.myOrderDetails,
page: () => const OrderDetailsPage(),
),
GetPage(
name: RouteNames.myOrderList,
page: () => const OrderListPage(),
),
GetPage(
name: RouteNames.myProfileEdit,
page: () => const ProfileEditPage(),
),
GetPage(
name: RouteNames.myTheme,
page: () => const ThemePage(),
),
GetPage(
name: RouteNames.searchSearchFilter,
page: () => const SearchFilterPage(),
),
GetPage(
name: RouteNames.searchSearchIndex,
page: () => const SearchIndexPage(),
),
GetPage(
name: RouteNames.stylesBottomSheet,
page: () => const BottomSheetPage(),
),
GetPage(
name: RouteNames.stylesButtons,
page: () => const ButtonsPage(),
),
GetPage(
name: RouteNames.stylesCarousel,
page: () => const CarouselPage(),
),
GetPage(
name: RouteNames.stylesComponents,
page: () => const ComponentsPage(),
),
GetPage(
name: RouteNames.stylesGroupList,
page: () => const GroupListPage(),
),
GetPage(
name: RouteNames.stylesInputs,
page: () => const InputsPage(),
),
GetPage(
name: RouteNames.stylesOther,
page: () => const OtherPage(),
),
GetPage(
name: RouteNames.stylesStylesIndex,
page: () => const StylesIndexPage(),
),
GetPage(
name: RouteNames.stylesText,
page: () => const TextPage(),
),
GetPage(
name: RouteNames.stylesTextForm,
page: () => const TextFormPage(),
),
GetPage(
name: RouteNames.stylesIcon,
page: () => const IconPage(),
),
GetPage(
name: RouteNames.stylesImage,
page: () => const ImagePage(),
),
GetPage(
name: RouteNames.systemLogin,
page: () => const LoginPage(),
),
GetPage(
name: RouteNames.systemMain,
page: () => const MainPage(),
),
GetPage(
name: RouteNames.systemRegister,
page: () => const RegisterPage(),
),
GetPage(
name: RouteNames.systemRegisterPin,
page: () => const RegisterPinPage(),
),
GetPage(
name: RouteNames.systemSplash,
page: () => const SplashPage(),
),
GetPage(
name: RouteNames.systemUserAgreement,
page: () => const UserAgreementPage(),
),
];
}

lib/pages/index.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
library common;

export 'api/index.dart';
export 'components/index.dart';
export 'extension/index.dart';
export 'i18n/index.dart';
export 'models/index.dart';
export 'routers/index.dart';
export 'services/index.dart';
export 'style/index.dart';
export 'utils/index.dart';
export 'values/index.dart';
export 'widgets/index.dart';

第 4 步: 让路由生效

编辑 main.dart

删掉 MyHomePage 定义

1
2
3
4
5
6
7
8
9
10
11
12
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return GetMaterialApp(
...

// 路由
initialRoute: RouteNames.systemSplash,
getPages: RoutePages.list,
navigatorObservers: [RoutePages.observer],

启动屏 splash

启动后是这样子

img

提交代码到 git

1
2
git add .
git commit -m "业务模块初始、路由注册"