Flutter(或者更宽泛的app开发)可以一句话总结为:

UI = f(state)

即app的当前界面(UI)反映了当前程序状态(state). Flutter的状态管理就是app根据当前app的state的显示和更新UI.

我们假设state是一个类型为T的object, 在下文的购物车例子中, state是当前购物车的内容(类型T=List<Item>).

关于如何在widget tree里获取state, 可以有provider/riverpod等选项, e.g.Provider<T>. 但是如果直接用T作为状态会有问题: 就是当state的值被修改以后, 对应的UI并不会自动rebuild(除非其他逻辑如setState触发了rebuild).

如果希望在state修改以后, UI自动触发监听它的UI更新, 则需要用各种Notifier来包裹state. 例如我们不用T作为state, 而是用ValueNotifier<T>.

这里主要介绍和比较三种常用的Notifier: ChangeNotifier ...

看了Resocoder和Robert Brunhage的两个视频, 这篇总结一下其中的内容(我其实还没实践过).

本文主要参考自: - pub package
- Video by Robert Brunhage
- Tutorial by Resocoder

The problem

Flutter hooks想解决的问题是StatefulWidget的一些常见pattern太复杂, 减少了代码的可读性("readability").

一个典型例子就是animation controller:

class MyPage extends StatefulWidget{
  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage>
    with SingleTickerProviderStateMixin {
  AnimationController _animController;

  @override
  void initState() {
    super.initState();
    _animController = AnimationController(
      vsync: this ...

这篇文章主要总结了FlutterEngage里的这个talk:

(这个talk的名字的中文翻译挺牛的: "小事一桩:成为开发和设计俱佳的神级人物")

talk里代码地址在: https://github.com/filiph/little_things

这个talk还是挺有意思的, 介绍了如何提升App的设计细节从而获得更高的 "Perceived value": 有时候app本身的功能性和技术性是一方面, 但是呈现给用户的感觉却有可能因为一点点细节而完全不同. 这一点我之前不太重视, 细想一下确实有道理.

1. White space

多使用padding添加空隙和留白, 体现一种高级感~ 结合Flutter的hot reload可以快的实验 找到合适的padding.

2. Typography

换个好看的字体也可以让应用看起来非常高级.

GoogleFont配合hot reload来选择好的字体

3. Color

给app添加特别的配色.

可以从网上找一些配色方案(color palette), 比如:

  • https://coolors.co/palettes/trending
  • https://undesign.learn.uno/colors/

把选好的ColorPalette放在MaterialApp ...

Dart默认的linter配置有点弱, 有很多有问题代码也不报错或警告. 添加一个analyzer可以应用dart的最佳代码实践, 对一些不好的代码风格提出警告或者直接报错, 从而提高代码质量.

Cf. resocoder的介绍文章 (和视频)

Use an analyzer

Resocoder推荐lint, 里面提供了一些最佳的dart和flutter代码风格. 类似的选择还有pandentic和effective_dart.

使用方式就是, 先在pubsepc.yaml里添加依赖:

# pubspec.yaml
dependency_overrides:
  lint: ^1.3.0

然后在根目录新建一个analysis_options.yaml文件:

# analysis_options.yaml
include: package:lint/analysis_options.yaml

Exclude folders / disable rules

analyzer默认会扫描文件夹下所有的dart代码, 有时候一些自动生成的代码或者在build/文件夹下的代码并不需要被分析, 可以用exclude把它们排除在外.

另外有些默认的规则可能不适用于自己的代码, 比如我就比较喜欢加this, 认为这样更容易区分成员变量和普通变量 ...

本文总结了Flutter Explained关于fvm的视频: https://youtu.be/R6vKde1vIGQ

background

flutter有很多channel: stable/beta/dev/master, 而目前有些功能只在某个channel上可用, 比如Linux support目前只在dev channel支持.

我日常用的是beta channel, 但是想写Linux程序时每次flutter channel dev的话 需要花费很多时间--因为要下载新channel的内容, switch回去的时候又要等半天(因为要从新下载).

fvm这正是解决这个问题的! 它可以cache不同版本的flutterSDK, 每个repo可以设置使用不同的版本号, 而且VSCode也只需要简单配置就能上手.

enable fvm

一行命令即可开启fvm: $ pub global activate fvm

常用法:

  • fvm flutter: Proxies flutter commands 用于选择合适的flutter版本
  • 也就是说用fvm flutter来代替flutter命令 ...