![猫哥视频站](images/video-ducafecat-banner.png)
© 猫哥
-
微信 ducafecat
- 插件配套项目
免费开源项目示例 flutter_ducafecat_news_getx 配套使用。
- 商业 APP 模版课程
欢迎使用我们的商业模版项目,快速开发你的项目并上线。
https://ducafecat.com/course/flutter-woo
- 腾讯 tim 即时通讯项目课程
https://ducafecat.com/course/flutter-tim
- 根据
x3
图片自动生成x1
x2
图片 - 生成
图片
svg
常量列表files.txt
- 生成规范目录
common
- 生成
GetBuilder + GetView
的代码 - 生成
StatefulWidget + GetBuilder + GetView
的代码 - 生成
controller、view、widgets、bindings、state、index
完整的代码 - 生成 路由声明定义文件
common/routers/names.txt common/routers/pages.txt pages/index.txt
目录上右键菜单操作
请将你的 图片
、Svg
放到目录
assets/images/
assets/svgs/
- 准备好你的
assets/images/3.0x
图片
- 右键点击菜单
Assets: Images x1 x2 Generate
- 成功生成了
2.0x
文件夹,和1x
的图片
点击 Assets: Images x1 x2 Generate
同时会生成常量列表文件 files.txt
文件位置
assets/images/files.txt
assets/svgs/files.txt
所以你的
图片
svg
要放到指定位置
- 生成
files.txt
常量列表
- 如果你把
svg
放到assets/svgs
这个目录下,也会生成常量列表
自动创建开发目录
- common
- api
- index.dart
- i18n
- models
- routers
- services
- style
- utils
- widgets
- pages
- index.dart
只有 controller、view 两个文件
推荐用这种,简单快速,自带自动释放控制器,GetBuilder 方式对性能也好。
- view
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'index.dart';
class AbcPage extends GetView<AbcController> {
const AbcPage({super.key});
Widget _buildView() {
return Container();
}
@override
Widget build(BuildContext context) {
return GetBuilder<AbcController>(
init: AbcController(),
id: "abc",
builder: (_) {
return Scaffold(
body: SafeArea(
child: _buildView(),
),
);
},
);
}
}
采用
GetBuilder
手动、布局控制刷新,性能好,推荐这种。 注意看这个id
属性,需要全局唯一
代码清单:
- controller
import 'package:get/get.dart';
class AbcController extends GetxController {
AbcController();
_initData() {
update(["abc"]);
}
void onTap() {}
// @override
// void onInit() {
// super.onInit();
// }
@override
void onReady() {
super.onReady();
_initData();
}
// @override
// void onClose() {
// super.onClose();
// }
// @override
// void dispose() {
// super.dispose();
// }
}
常用的生命周期函数也生成了,按需要放开注释
update(["abc"]);
采用这种方式出发GetBuilder
的id
属性,进行控制刷新
这种是在 GetBuilder + GetView 的基础上,再加入了 StatefulWidget 包裹,比如你需要 mixin 一些功能的时候需要(AutomaticKeepAliveClientMixin、wantKeepAlive)。
代码清单:
- controller
import 'package:get/get.dart';
class MyController extends GetxController {
MyController();
_initData() {
update(["my"]);
}
void onTap() {}
// @override
// void onInit() {
// super.onInit();
// }
@override
void onReady() {
super.onReady();
_initData();
}
// @override
// void onClose() {
// super.onClose();
// }
// @override
// void dispose() {
// super.dispose();
// }
}
- view
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'index.dart';
class MyPage extends StatefulWidget {
const MyPage({super.key});
@override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage>
with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return const _MyViewGetX();
}
}
class _MyViewGetX extends GetView<MyController> {
const _MyViewGetX({super.key});
Widget _buildView() {
return Container();
}
@override
Widget build(BuildContext context) {
return GetBuilder<MyController>(
init: MyController(),
id: "my",
builder: (_) {
return Scaffold(
body: SafeArea(
child: _buildView(),
),
);
},
);
}
}
可以看到
GetX
和StatefulWidget
的优雅的结合方式,就是作为组件在StatefulWidget.build
时创建 并不是用了GetX
就不要StatefulWidget
了,很多Mixin
还是需要的
鼠标右键你的视图目录,输入名称生成代码
这种方式,包含了全部的 controller、view、widgets、bindings、state 拆分的很细致
代码清单:
- controller
import 'package:get/get.dart';
import 'index.dart';
class AccountController extends GetxController {
AccountController();
final state = AccountState();
// tap
void handleTap(int index) {
Get.snackbar(
"标题",
"消息",
);
}
/// 在 widget 内存中分配后立即调用。
@override
void onInit() {
super.onInit();
}
/// 在 onInit() 之后调用 1 帧。这是进入的理想场所
@override
void onReady() {
super.onReady();
}
/// 在 [onDelete] 方法之前调用。
@override
void onClose() {
super.onClose();
}
/// dispose 释放内存
@override
void dispose() {
super.dispose();
}
}
- view
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'index.dart';
import 'widgets/widgets.dart';
class AccountPage extends GetView<AccountController> {
const AccountPage({super.key});
// 内容页
Widget _buildView() {
return const HelloWidget();
}
@override
Widget build(BuildContext context) {
return GetBuilder<AccountController>(
builder: (_) {
return Scaffold(
body: SafeArea(
child: _buildView(),
),
);
},
);
}
}
- bindings
import 'package:get/get.dart';
import 'controller.dart';
class AccountBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<AccountController>(() => AccountController());
}
}
- state
import 'package:get/get.dart';
class AccountState {
// title
final _title = "".obs;
set title(value) => _title.value = value;
get title => _title.value;
}
- index
library account;
export './state.dart';
export './controller.dart';
export './bindings.dart';
export './view.dart';
- widgets/hello.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../index.dart';
/// hello
class HelloWidget extends GetView<AccountController> {
const HelloWidget({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Obx(() => Text(controller.state.title)),
);
}
}
- widgets/widgets.dart
library widgets;
export './hello.dart';
common/routers/names.txt
common/routers/pages.txt
pages/index.txt
lib/common/routes/names.txt
static const application = '/application';
static const category = '/category';
static const frameNotfound = '/frame_notfound';
static const frameSignIn = '/frame_sign_in';
static const frameSignUp = '/frame_sign_up';
static const frameWelcome = '/frame_welcome';
static const main = '/main';
lib/common/routes/pages.txt
GetPage(
name: RouteNames.application,
page: () => const ApplicationPage(),
),
GetPage(
name: RouteNames.category,
page: () => const CategoryPage(),
),
GetPage(
name: RouteNames.frameNotfound,
page: () => const FrameNotfoundPage(),
),
GetPage(
name: RouteNames.frameSignIn,
page: () => const FrameSignInPage(),
),
GetPage(
name: RouteNames.frameSignUp,
page: () => const FrameSignUpPage(),
),
GetPage(
name: RouteNames.frameWelcome,
page: () => const FrameWelcomePage(),
),
GetPage(
name: RouteNames.main,
page: () => const MainPage(),
),
lib/pages/index.txt
export 'application/index.dart';
export 'category/index.dart';
export 'frame/notfound/index.dart';
export 'frame/sign_in/index.dart';
export 'frame/sign_up/index.dart';
export 'frame/welcome/index.dart';
export 'main/index.dart';
好了 拿去复制吧,这样不用自己手写了!
end
大家可以自己动手体验下~
© 猫哥
-
微信 ducafecat
![猫哥视频站](images/video-ducafecat-banner.png)