Flutter开发杂记

168 阅读3分钟

熟悉了下dart语言后,就直接上手开发flutter项目。由于这个项目比较简单,算是入门级的项目,就没啥比较复杂的东西,这是开发过程中的记录。

一.组件

1.网络请求

Dio和http库网上一大堆资料介绍的,就不一一介绍了。 因为第一次使用flutter入门开发,不考虑请求超时等其他因素,就用比较手容易的http库了。

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<Stringdynamic>?> 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<Stringdynamic> ? result;  
  final int? count;  
  
  ApiResponse(this.code,this.msg, this.result,this.count);  
  
  factory ApiResponse.fromJson(Map<Stringdynamic> json) => _$ApiResponseFromJson(json);  
  
  Map<Stringdynamic> toJson() =>  _$ApiResponseToJson(this);  
  
}

2.json解析

由于flutter没有反射机制,导致不能想java那样用Gson等库来解析json,可以用Map(json['data'])的形式拿到。有强迫症的同学非要对象怎么办? 这时就用到json_serializable库。

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<Stringdynamic> json) => _$TaskSubFromJson(json);  
  
  Map<Stringdynamic> toJson() => _$TaskSubToJson(this);  
}

3)、运行build_runner

在终端运行

flutter pub run build_runner build

这样就生成一个task_sub.g.dart文件

4)、使用

TaskSub taskSub = TaskSub.fromJson(json);

3.数据存储

shared_preferences

4.Toast

fluttertoast

5.获取设备基本信息库

device_info_plus

6.权限

permission_handler

7.webView

webview_flutter

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)  
    );  
  }  
}