持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
pubspec.yaml
name: life
description: A new Flutter project.
environment:
sdk: ">=2.17.0-0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
flutter_screenutil: ^5.4.0+1 * 屏幕适配工具
flutter_picker: ^2.0.3 * 底部弹出选择器
dotted_border: ^2.0.0+2 * 虚线边框
flutter_swipe_action_cell: ^2.2.0 * 滑动操作
images_picker: ^1.2.11 * 图片选择器,允许相机拍照
flutter_easyloading: ^3.0.3 * 弹出提示组件
keyboard_dismisser: ^2.0.1 * 键盘自动收起
dio: ^4.0.6 * 网络请求
get: ^4.6.1 * 状态管理、路由管理
get_storage: ^2.0.3 * 内部存储管理
flutter_swiper: ^1.1.6 * 轮播组件
webview_flutter: ^3.0.4 * webview组件
photo_view: * 图像预览组件(git仓库版本解决了某些bug)
git:
url: https://github.com/bluefireteam/photo_view
ref: master
fluwx_no_pay: ^3.8.5 * 微信互动
scan: ^1.6.0 * 扫码组件
jpush_flutter: ^2.2.9 * 极光推送
dev_dependencies:
flutter_test:
sdk: flutter
assets:
- assets/images/tabbar/home.png
fonts:
- family: IconFont
fonts:
- asset: assets/font/iconfont.ttf
- 项目依赖:dependencies\
- 尽量制定最新版本引用,避免使用仓库地址引用\
- 富逻辑插件,在utils做一层包装,确定使用逻辑后,避免更新组件
- 图片:assets
-
- 必须完整路径引用
-
- 删除引用必须删除assets目录下对应文件
- 字体: fonts
-
- iconfont字体在此处使用
编码
组件
Flutter 中所有的显示均由组件构成,框架本身提供了包含Material和Cupertino两种风格200+组件
Flutter组件大概可以分为布局、图文、事件、装饰等几个大类
自定义组件
- 有状态组件
有相应的生命周期,可以响应数据变化,较之无状态组件开销更大的内存,因为我们的项目引入了GetX,所以不建议使用
如果需要响应数据,之后会有说明
class MyWidget extends StatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
late String title;
@override
void initState() {
super.initState();
setState(() {
title = '有状态';
});
}
@override
void didChangeDependencies() {
// 调用initState会调用
// 从其他对象中依赖一些数据发生改变时
super.didChangeDependencies();
}
@override
void didUpdateWidget(state) {
// 当父组件触发rebuild
super.didUpdateWidget(state);
}
@override
Widget build(BuildContext context) {
return Text(title);
}
@override
void dispose() {
//组件销毁时
super.dispose();
print('组件被销毁');
}
}
- 无状态组件
组件创建完成不能再被更新
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
final title = '无状态';
@override
Widget build(BuildContext context) {
return Text(title);
}
}
//函数式组件
Widget myWidget(title){
return Text(title);
}
组件传参
组件之间常用的参数传递方法
class Fa extends StatelessWidget {
const Fa({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Son(title:'标题',
valChanged:(val){
print(val);
}
)
}
}
↓↓↓ ↑↑↑
class Son extends StatelessWidget {
const Son({Key? key,
this.title='暂无标题',//非必填,需要默认赋值
required this.valChanged //回调子传父
}}) : super(key: key);
const Son({Key? key,required this.title}) : super(key: key);//必填,声明加上required
final String title;
final ValueChanged valChanged;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (val) =>valChanged(val),//子传父调用
child: Text(title)//父组件传过来的
)
}
}
GetX的使用
GetX是一个由开源社区发布的Flutter状态管理与路由管理及其他工具的一个集合插件
- 数据的双向绑定
class Logic extends GetxController {
RxList<dynamic> msgList = [].obs;
void getMsgList() {
msgList.value = [
{'name': '周生', 'num': 25},
{'name': '王生', 'num': 24}
];
update();
}
}
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final logic = Logic();
logic.getMsgList();
return Obx(()=>Text(logic.msgList[0].name));//添加点击事件不需要setState就可以改变msgList并反应在视图
}
}
- 路由管理
Getx路由相较于flutter自带的路由略去了上下文,可以更方便的随处调用,同时也更简单的提供了中间件的实现,详见utils/router
常用组件
以下仅是简单示例,属性繁多,请查看官方文档
Container
创建一个指定宽高、对齐方式、装饰属性的容器(只指定宽高可替代为SizedBox)
Container(
margin: EdgeInsets.only(top: 20.h,left: 20.w),
width: double.infinity,//匹配父组件宽度(父组件需固定宽度)
height: 200.h,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.red, width: 1),
),
)
//margin/padding属性常用取值
* EdgeInsets.all(10.r)//统一距离
* EdgeInsets.only(top: 20.h,left: 20.w)//指定方向
* EdgeInsets.symmetric(horizontal: 36.w,vertical: 20.h)//指定轴向
Flex、Row、Column
创建一个制定轴向的排列容器(Flex需要通过属性定义轴向)
Row/Column(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [
A(),B()
],
)