此篇介绍初期学习Flutter的一些知识。

环境安装

  1. 由于国内访问限制,首先需要设置Flutter镜像环境变量(解决被墙导致的失败问题)
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
  1. 下载Flutter SDK

git clone -b stable https://github.com/flutter/flutter.git

并将Flutter的Bin目录加入到PATH中

export PATH=pwd/flutter/bin:$PATH

  1. 运行 flutter doctor 命令检查环境是否已正确配置,如有错误需逐项解决

macOS 可以允许开发 iOS、Android 和 Web(技术预览版正式发布)三个平台的 Flutter 应用

  1. 要为Android开发Flutter应用,需要在电脑上安装和配置Android Studio,并在手机设备上启用“开发人员选项”和“USB调试”。或者使用Visual Studio Code,并安装flutter插件使用

  2. 如使用VSCode,“查看”——“命令面板”——“Flutter:New Project”创建新的Flutter项目,使用“调试”——“启动调试”可以传输包到模拟器上,并显示效果,修改后还可以使用热重载观看修改后的效果

示例代码

第一个Flutter应用的代码:startup_name_generator

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Startup Name Generator',
      theme: new ThemeData(
        primaryColor: Colors.white,
      ),
      home: new RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  createState() => new RandomWordsState();
}

class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];

  final _saved = new Set<WordPair>();

  final _biggerFont = const TextStyle(fontSize: 18.0);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Startup Name Generator'),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved)
        ],
      ),
      body: _buildSuggestions(),
    );
  }

  Widget _buildSuggestions() {
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: (context, i) {
        if (i.isOdd) return new Divider();

        final index = i ~/ 2;
        if (index >= _suggestions.length) {
          _suggestions.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_suggestions[index]);
      },
    );
  }

  Widget _buildRow(WordPair pair) {
    final alreadySaved = _saved.contains(pair);
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: new Icon(
        alreadySaved ? Icons.favorite : Icons.favorite_border,
        color: alreadySaved ? Colors.red : null,
      ),
      onTap: () {
        setState(
              () {
            if (alreadySaved) {
              _saved.remove(pair);
            } else {
              _saved.add(pair);
            }
          },
        );
      },
    );
  }

  void _pushSaved() {
    Navigator.of(context).push(
      new MaterialPageRoute(
        builder: (context) {
          final tiles = _saved.map(
                (pair) {
              return new ListTile(
                title: new Text(
                  pair.asPascalCase,
                  style: _biggerFont,
                ),
              );
            },
          );
          final divided = ListTile
              .divideTiles(
            context: context,
            tiles: tiles,
          )
              .toList();

          return new Scaffold(
            appBar: new AppBar(
              title: new Text('Saved Suggestions'),
            ),
            body: new ListView(children: divided),
          );
        },
      ),
    );
  }
}

简单命令

flutter create myapp   //创建Flutter工程
flutter devices  //查看运行的设备
flutter run  //运行应用程序
flutter build ios --debug  //iOS debug模式打包
flutter build ios --release  //iOS release模式打包(release包不能在模拟器上正常运行)
flutter channel  //查看当前channel
flutter channel beta //切换到beta channel
flutter upgrade  //升级

将项目运行在模拟器上

  1. 注意Project name必须以小写字母开头,而且不可以有空格。

Flutter的热修复特性

  1. Flutter具有热修复(在某些情况下称之为热重载)特性。所谓热修复,是指无需重新启动App,即可快速的将修改后的源代码文件注入正在运行的Dart虚拟机中,而Dart虚拟机会立即套用修改后的代码。
  2. Flutter框架会自动重新构建组件树实现热修复。
  3. 有几种情况下无法执行热修复:
    (1)代码编译错误
    (2)修改后的代码影响了修改前的状态(即数据)
    (3)对于静态字段如final修饰的常量值,在修改后不会变化,仍未修改前的值
    (4)对于UI组件,如果修改后的代码不会因为重新构建Widget组件树而被重新执行的话,热修复就对其不起作用,并且不会抛出任何异常
    (5)枚举类型更改为常规类,或常规类更改为枚举类型,都会导致热修复失败
    (6)更改泛型类型声明会导致热修复失败

升级Flutter

1、升级Flutter SDK可以执行命令

flutter upgrade

命令会获取最新稳定版本,并在升级后自动执行flutter doctor命令来检查环境配置

  1. 升级依赖库
    App可能会依赖多个库,这些库在pubspec.yaml文件中被列出。如果要获取依赖库,需要执行命令:

flutter packages get

如果想升级依赖库到最新版本,需要执行命令:

flutter packages upgrade

命令行编译包

生成Android平台App包:

flutter build apk

生成iOS平台App包:

flutter build ios