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 ...

写公众号最好的时机是五年前, 其次是现在.

==> 所以我俩月前注册了个微信公众号🐱:

而拖延两个月以后, 这周末体验了撰写和发布公众号的流程, 感觉还是和通过github发布blog有点区别的, 这里记录一下.

将markdown转换为公众号文章

微信公众号的编辑界面类似word, 我从markdown导过去的话需要借用第三方工具. 其实这种工具还挺多的, 我找到了三个:

我最推荐的是最后一个网站"mdnice", 和另外两个相比有不少优点:

  1. 支持各种排版主题
  2. 登录帐号以后可以保存多个最近编辑的文件 -- 虽说理论上只要直接复制粘贴markdown就好, 但是说不定就要针对公众号进行调整, 所以能保存一个针对公众号的
  3. 支持把外链转换为脚注(见下文)
  4. 支持不少代码块主题
  5. 代码块太长时可以横向滚动
  6. 还支持Mac风格的代码块, 看上去很高级:

嵌入视频

普通markdown里可以添加youtube或者B站的iframe html代码嵌入视频. 但是微信公众号不支持这个功能.

似乎只支持嵌入腾讯视频上的内容, 或者把视频手动上传到素材中然后嵌入.

不支持外链

微信公众号仅支持公众号文章链接,即域名为https://mp ...

看了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命令 ...

2016年的最后几小时, 随便写写关于Scala和OCaml的一些入门体验好了.

今年对FP语言特别感兴趣, 上了两门Scala的公开课(here and here)和一门OCaml的公开课(here), 在博客中写了一系列的笔记, 课后作业也都认真做完了. 斗胆说这两门语言都算入门了吧... 这里就随便写一下使用这两门语言的感受, 想到哪里写到哪里...

FP语言和之前接触的语言确实不大一样, 比如之前我都有种错觉, 学什么语言只要知道循环/条件/基本类型运算怎么写, 就差不多可以上手了...... 然后遇到了FP, 发现循环语句其实是不必要的... 记得看到过一篇文章, 类比学FP就好像开了很多种车的老司机突然开始学开宇宙飞船, 肯定各种WTF不适应了~

以前谈到FP我只能联想到一些Python里的FP特性: lambda表达式, 高阶函数之类的, 顶多还想到个闭包... 不过Python里面的FP特性和Scala/OCaml里的比起来还是差了不少: i.e. 现在非常希望Python里可以支持pattern matching...

Scala

Scala算是比较亲民的FP语言了(和Java有点像...), 也是我最早接触的FP语言. EPFL的那两门公开课质量很棒, 毕竟是Scala的作者亲自来上的...

  • immutable types: 习惯了就好, 就像java里所有东西都是final的, 要修改什么东西的时候改成新建一个, immutable数据的优点就是并行方便啊...
  • 一切皆为表达式, specifically, if ...

前一段时间写了不少Python的爬虫程序, 为此还看了极客学院上的一些教程, 现在来简单总结一下. 主要介绍用requests + lxml的方式, scrapy的话之前写过一篇介绍性的文章, 这里就不重复了. 而且感觉一般简单的爬虫项目, 一个Python文件就基本可以搞定, 没必要用scrapy建立一个工程文件夹搞那么正式...

安装需要的库(python2):

pip install requests, lxml

然后在Python程序最开始导入:

import requests  
from lxml import etree

requests基础用法

抓取html内容

用requests获取目标网址的html代码非常简单, 只需要用requests.get方法, 传入网址URL即可.

举个例子, 想要抓取维基语录的HTML内容, 代码很简单:

url = 'https://zh.wikiquote.org/zh-cn/阿爾伯特·愛因斯坦'  
r ...

总结一下用python撸codejam时常用的一些库, 并且给一些简单的例子. 发现用python撸codejam非常合适: codejam的时间要求不严格(4/8分钟), 而且程序只要本地运行. 正好可以使用python简洁的语法和丰富的函数库.

collections

py自带的一些好用的数据结构...
https://docs.python.org/2/library/collections.html

from collections import Counter, deque, defaultdict

itertools

主要是用来穷举的时候它里面一些函数很好用...

https://docs.python.org/2/library/itertools.html

>>> from itertools import product, combinations   
>>> a = 'ABCD'; b='EFG'   
>>> for p in product(a,b):    
print ...