熟悉了下dart语言后,就直接上手开发flutter项目。由于这个项目比较简单,算是入门级的项目,就没啥比较复杂的东西,这是开发过程中的记录。
一.组件
1.网络请求
Dio和http库网上一大堆资料介绍的,就不一一介绍了。 因为第一次使用flutter入门开发,不考虑请求超时等其他因素,就用比较手容易的http库了。
1)、首先在pubspec.yaml文件中dependencies下加入
http: ^1.2.1
2)、使用
import 'package:http/http.dart' as http;
final response =http.get(Uri.parse(mUrl.toString()), headers: HttpUtil.getHeaderParamMap(param))
//处理返回数据
processResponse(response)
3)、解析数据
///解析数据
static Future<Map<String, dynamic>?> processResponse(http.Response response) async {
final data = utf8.decode(response.bodyBytes);
if (response.statusCode == 200) {
final ApiResponse apiResponse = ApiResponse.fromJson(jsonDecode(data));
//服务器返回的code
final code = apiResponse.code;
if( code == AppConfig.sucess_code){
//请求成功
return apiResponse.result;
}else if( code == AppConfig.http_invalid_token){
//身份信息过期
throw HttpInvalidException(apiResponse.msg);
}else{
//其他报错
throw HttpErrException(apiResponse.msg);
}
} else {
throw Exception('Failed to load ApiResponse');
}
}
4)、然后是model类
@JsonSerializable()
class ApiResponse {
final int code;
final String msg;
final Map<String, dynamic> ? result;
final int? count;
ApiResponse(this.code,this.msg, this.result,this.count);
factory ApiResponse.fromJson(Map<String, dynamic> json) => _$ApiResponseFromJson(json);
Map<String, dynamic> toJson() => _$ApiResponseToJson(this);
}
2.json解析
由于flutter没有反射机制,导致不能想java那样用Gson等库来解析json,可以用Map(json['data'])的形式拿到。有强迫症的同学非要对象怎么办?
这时就用到json_serializable库。
1)、首先在pubspec.yaml文件中dependencies下加入
dependencies:
flutter:
sdk: flutter
json_annotation: ^4.8.1 # 请检查最新版本
dev_dependencies:
flutter_test:
sdk: flutter
json_serializable: ^6.7.1 # 请检查最新版本
build_runner: ^2.2.0 # 请检查最新版本
2)、使用
创建task_sub.dart类,并在类前添加@JsonSerializable() ,具体配置如下
import 'package:json_annotation/json_annotation.dart';
part 'task_sub.g.dart';
@JsonSerializable()
class TaskSub {
final int id;
final int taskId;
TaskSub(
this.id,
this.taskId,
);
factory TaskSub.fromJson(Map<String, dynamic> json) => _$TaskSubFromJson(json);
Map<String, dynamic> toJson() => _$TaskSubToJson(this);
}
3)、运行build_runner
在终端运行
flutter pub run build_runner build
这样就生成一个task_sub.g.dart文件
4)、使用
TaskSub taskSub = TaskSub.fromJson(json);
3.数据存储
4.Toast
5.获取设备基本信息库
6.权限
7.webView
8.国际化l10n
类似于Android的国际化,在res下生成多个values。flutter的国际化也差不多,在lib/l10n文件夹下创建对应语言的arb文件。
注意:与flutter_gen库冲突。会报错
Target of URI doesn't exist: 'package:flutter_gen/gen_l10n/app_localizations.dart'.
因为l10n在pubspec.yaml需要在文件中配置generate: true。
解决方案:删掉flutter_gen库。
二、语法
1.GlobalKey的使用
由于flutter是树结构。父Widget想用子Widget的字段时,我们通常是把这个字段从父Widget一级一级的传到子Widget中,但这样会导致父Widget体积变的越来越大,各种用得到用不到的字段都在父Widget内,用起来就比较难受了。GlobalKey就是为了解决这个问题诞生的。GlobalKey就不过多介绍了,资料一大把,就简单的介绍用法,有这样一个概念就行了。
final GlobalKey<_PageChangerState> _pageChangerState = GlobalKey();
PageChanger( key:_pageChangerState,);
//获取_pageChangerState内的字段
_pageChangerState.currentState?.page
2.不建议子Widget修改父Widget
不建议
class _PageAState extends State<PageA> {
int page = 1;
@override
Widget build(BuildContext context) {
return PageB(page:page);
}
}
class PageB extends StatefulWidget {
int page = 1;
PageB({super.key,required this.page});
@override
State<PageB> createState() => _PageBState();
}
class _PageBState extends State<PageB> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: (){
setState(() {
widget.page++;
}
},
child: Icon(Icons.add)
);
}
}
建议
class _PageAState extends State<PageA> {
int page = 1;
@override
Widget build(BuildContext context) {
return PageB(onClickAble:() => _add());
}
_add(){
setState(() {
page++;
});
}
}
class PageB extends StatefulWidget {
final Function()? onClickAble;
const PageB({super.key,this.onClickAble});
@override
State<PageB> createState() => _PageBState();
}
class _PageBState extends State<PageB> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: (){
widget.onClickAble?.call();
},
child: Icon(Icons.add)
);
}
}