0%

Flutter开发7个建议,让你的工作效率飙升

 10 5.png

刚开始接触用 Flutter 开发App的时候,比较喜欢它的 UI 编写方式,尤其是 Flutter 热重载特性,UI调试如同Web前端开发,能够即时查看代码更改的效果。那在日常开发中,还有没有其它提升工作效率的方法呢,今天就给大家分享几个超实用的建议,助你在 Flutter 开发中事半功倍。

1. 使用 Code Snippets

如果之前做过原生的 iOS 或者 Android 再来写 Flutter 代码的时候,Flutter 在代码提示上会不习惯,比如 for 循环,Flutter 的代码提示是 foreach 或者 for(var a in arr) 这些。

1
2
3
4
5
6
7
8
9
List<String> items = ["Flutter", "iOS", "Android"];
items.forEach((element) {
print(element);
});

// 或者
for (var element in items) {
print(element);
}

当我们需要数组的索引的时候,就需要手写一遍:

1
2
3
4
for (int i = 0; i < items.length; i++) {
var element = items[i];
print(element);
}

这个时候我们可以这些常用的代码保存到自己的 Code Snippets 中,具体操作根据编辑器不同而不同,这里以 Android Studio 为例,Setting -> Editor -> Live Templates
添加 Code Snippets

使用的时候输入:fori 编辑器就会有提示,选中回车后就是保存的Code Snippets,是不是很方便。

2. 使用代码生成器

开发过程中有大量重复的代码或者操作,这个时候使用代码生成器可以自动生成重复性的代码,减少开发人员手动编写模板代码的工作量。这样可以节省大量的时间和精力,并使开发人员能够更专注于解决业务逻辑和UI设计等核心任务。不同于Code Snippets 需要依赖编辑器的设置,这生成的代码则使用插件或者工具来完成。

下面是我经常使用的代码生成器插件或者工具:

  1. flutter_gen:项目图片资源、字体、颜色等的代码生成器。
    1
    2
    3
    Widget build(BuildContext context) {
    return Image.asset('assets/images/profile.jpeg');
    }
    使用 flutter_gen 之后,显示图片的时候再也不需要填入字符串了。
    1
    2
    3
    Widget build(BuildContext context) {
    return Assets.images.profile.image();
    }
  2. intl_utilsIntl 库样板代码生成器,用于在 .arb 文件的翻译和 Flutter 应用程序之间创建绑定。
    1
    Text(AppLocalizations.of(context)!.translate('intl_zh')),
    使用 intl_utils 生成的模板代码:
    1
    2
    3
    4
    5
    Text(
    S.of(context).intl_zh,
    style: const TextStyle(
    color: Color(0xFFffffff), fontSize: 22),
    )
  3. ftool:我自己开发的一款 JSON 字符串转成 Dart Model 生成器工具。
    JSON 字符串转成 Dart Model

其它的还有很多,如:Bloc GeneratorProvider Generator 等状态管理相关的模板代码生成器,我就不在这里一一列举了。

3. 应用图标生成

Flutter 应用图标需要支持多个平台,如果每一张不同尺寸的图标都去手动切的话,太麻烦,这里推荐一个插件工具 flutter_launcher_icons,只需要几个配置就可以自动生成各个平台的应用图标。

1
2
3
4
5
6
7
8
9
dependencies:
flutter_launcher_icons: ^0.13.1

flutter_icons:
image_path: "images/image.png"
android: true
ios: true
#image_path_ios: "images/image.png"
#image_path_android: "images/image.png"

命令行工具里执行下面命令就可以了。

1
flutter pub run flutter_launcher_icons

如果你还是觉得麻烦,不想引入这个插件,可以使用在线工具,网上也有很多。

4. CI/CD

持续集成(CI)和持续交付(CD)在开发过程中的好处有很多,特别是对于使用 Flutter 做跨平台开发 App 来说,如果用传统手动的方式打包提测那就太耗时间了,CI/CD 可以做快速地构建和部署应用程序,节省宝贵的时间也最大限度地减少人为错误,

CI/CD

团队开发更是如此,能确保所有团队成员都在同一个一致的构建环境中工作,这有助于避免由于环境差异而导致的问题。我们常使用工具有 Fastlane,它在 Flutter 项目中的详细用法以后抽个时间会专门写一篇文章来介绍。

5. 清晰的应用架构

不管是大型还是小型的 Flutter 应用,一个清晰的应用架构设计也是不可或缺的,尤其是在团队开发的时候,每个人项目经验、代码风格各不相同,如果碰上项目赶工期的话,那写出来的除了本人其它人都看不懂,时间久了有可能他自己也看不懂了。这时候,清晰的应用架构使团队成员之间更容易合作和协同工作。每个人都可以清楚地了解项目的结构和设计,从而更好地分工合作,提高开发效率。

Flutter App Architecture Design

你可能会说应用架构的设计和使用并不是很简单和直接,甚至还有些繁琐,怎么能提升开发效率?关于 Flutter 应用架构的设计和实践相关的疑问,可以翻一翻我之前的两篇文章:《Flutter大型项目架构:状态管理篇》《Flutter大型项目架构:分层设计篇》,也许你会从中找到答案。

6. 依赖注入

说到依赖注入那就不得不提 get_it,在 Flutter 开发里知名度高使用人数众多,那它是如何做依赖管理的呢?我在 get_it 的官方文档找到了这句话。

it’s a way to decouple the interface (abstract base class) from a concrete implementation, and at the same time allows to access the concrete implementation from everywhere in your App over the interface.

大概意思就是:它是一种将接口(抽象基类)与具体实现解耦的方法,同时允许通过接口从应用程序中的任何位置访问具体实现。

Flutter 中是不支持反射的,而大多数传统的 IoC 容器要依赖于反射,get_it 的作者就借鉴了 .Net 中的服务定位器(ServiceLocator)的概念,并运用到了 Flutter 中,相比于传统的 IoC 容器,get_it 更加轻量简洁。

我们怎么使用 get_it 呢?get_it 文档写的很详细了,但本篇文章介绍另外一种使用方法,就是和 injectable 插件一起使用,下面是简单的示例用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
abstract class Repository {
Future<void> login({
required String email,
required String password,
});
}

@LazySingleton(as: Repository)
class RepositoryImpl implements Repository {
@override
Future<void> login({
required String email,
required String password,
}) async {
// 登录操作,发送网络请求
}
}

命令行运行:flutter packages pub run build_runner build 命令后,就会自动生成以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import 'package:get_it/get_it.dart' as _i1;
import 'package:injectable/injectable.dart' as _i2;

extension GetItInjectableX on _i1.GetIt {
// initializes the registration of main-scope dependencies inside of GetIt
Future<_i1.GetIt> init({
String? environment,
_i2.EnvironmentFilter? environmentFilter,
}) async {
final gh = _i2.GetItHelper(
this,
environment,
environmentFilter,
);
gh.lazySingleton<_i3.Repository>(() => _i4.RepositoryImpl());
return this;
}
}

业务层调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Injectable()
class LoginBloc extends BaseBloc<LoginEvent, LoginState> {
LoginBloc(this._repository) : super(LoginState()) {
on<LoginButtonPressed>(
_onLoginButtonPressed,
transformer: log(),
);
}
final Repository _repository;

FutureOr<void> _onLoginButtonPressed(LoginButtonPressed event, Emitter<LoginState> emit) {
_repository.login(email: "", password:"");
}
}

上面代码中以发送登录请求为例,在业务层使用的直接调用抽象类 Repositorylogin 函数,而具体实现则在 RepositoryImpl 中,很好的隔离业务层和数据处理层,使得他们之间的连接都是通过抽象层 Repository ,这中间的依赖关系不再需要你写任何代码,get_it 配合 injectable 帮你生成了,这样管理和解耦应用程序的组件更加方便了,特别是跨组件调用的时候,提高代码的可维护性、可测试性和灵活性。

7. Github Copilot

一款由 GitHubOpenAI 共同开发的人工智能代码编写助手,它基于 GPT 模型生成代码建议,可以根据上下文和用户输入提供代码提示和建议,帮助开发者快速编写代码。还能能够生成函数、类、变量声明等各种类型的代码片段,并提供自然语言描述的文档注释。

Copilot

用过的就不需要我多说了吧,好用是真好用,就是有点儿小贵(对于小编来说),初学者使用它简直太香了,可以直接把 Copilot 作为学习工具,用来学习编程语言和编码风格。

以上与插件相关的内容着重在提升效率的说明上,详细用法还是要去阅读官方文档。以上建议是小编在开发过程中经常使用到的,也仅代表我个人的观点,当然还有更多其它提升效率的方法。好了,本篇文章分享就到这里,感谢您的阅读,原创不易,记得关注加点赞哦。