Hello Flutter

136 阅读2分钟

前言

通过本文你将了解到关于flutter的环境搭建、项目结构分析,用户交互等相关内容。

环境搭建

  • 从 GitHub 上的 Flutter repo 获取源代码。

    git clone https://github.com/flutter/flutter.git -b stable
    
  • 配置环境变量,可参考PATH 环境变量配置

    export PATH="$PATH:[PATH_TO_FLUTTER_GIT_DIRECTORY]/flutter/bin"
    
  • 运行 flutter doctor 命令,查看当前环境是否需要安装其他的依赖。

    flutter doctor
    
  • 平台配置,下面以Android平台举例。

    • 安装 Android Studio,3.0 或之后的版本。
    • 安装 Flutter 和 Dart 插件。
    • 配置 Android 设备。
  • 创建并运行应用。

    • 打开 IDE,选择 新 Flutter 项目 (Start a new Flutter project)。
    • 点击工具栏中的 Run 图标,或者在菜单中选择 Run > Run。

flutter项目结构

hello_flutter
  ┬
  ├ android      - 包含 Android 特定的文件。
  ├ build        - 存储 iOS 和 Android 构建文件。
  ├ ios          - 包含 iOS 特定的文件。
  ├ lib          - 应用源文件。
    ┬
    └ src        - 包含额外的源文件。
    └ main.dart  - 程序运行入口文件。
  ├ test         - 测试文件。
  └ pubspec.yaml - 应用程序的依赖包配置。

  • android目录

    这里存放的是Flutter与android原生交互的一些代码,这个路径的文件和创建单独的Android项目的基本一样的。

  • ios目录

    这里存放的是Flutter与ios原生交互的一些代码。

  • lib目录

    这里存放的是Dart语言编写的代码,代码将运行到多个平台上。hello_flutter例子中,就是运行的lib目录下的main.dart这个文件。我们可以在lib目录下面创建不同的文件夹,来管理文件。

  • pubspec.yaml文件

    这个是依赖项的配置文件,类似于Android的build.gradle文件,例如:

    dependencies:
      flutter:
        sdk: flutter
    
      # The following adds the Cupertino Icons font to your application.
      # Use with the CupertinoIcons class for iOS style icons.
      cupertino_icons: ^0.1.2
    
  • 资源文件

    像图片、视频、文字等这些资源文件,在 Flutter 里是可以直接引用的,不过需要对资源进行声明式说明。 在 pubspec.yaml 里进行声明。

    flutter:
      assets:
        - assets/app_icon.png
        - assets/background.png
    

    在代码里这样进行引用。

    new Image(image: new AssetImage('assets/background.png'));
    

hello_flutter项目分析

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
  • 本示例创建了一个具有 Material Design 风格的应用, Material 是一种移动端和网页端通用的视觉设计语言, Flutter 提供了丰富的 Material 风格的 widgets。
  • 主函数(main)使用了 (=>) 符号,这是 Dart 中单行函数或方法的简写。
  • 该应用程序一共出现了2种widget,一种是StatelessWidget(无状态),另一种是StatefulWidget(有状态)。在 Flutter 中,几乎所有都是 widget,包括对齐 (alignment)、填充 (padding) 和布局(layout)。
  • Scaffold 是 Material 库中提供的一个 widget,它提供了默认的导航栏、标题和包含主屏幕 widget 树的 body 属性。
  • 一个 widget 的主要工作是提供一个 build() 方法来描述如何根据其他较低级别的 widgets 来显示自己。
  • 本示例中的 body 的 widget 树中包含了一个 Center widget, Center widget 又包含一个 Column 子 widget,Column widget 又包含2个 Text 子 widget,widget 树可以很复杂。

flutter响应用户交互

通过例子我们可以看到当用户点击‘+’button时计时器随着递增,那么这是如何做到的呢? 当点击floatingActionButton时,会调用_incrementCounter方法,接着调用了setState方法,当setState方法被调用时,flutter框架会对当前的wodgets树进行diff,并触发重绘,此时_counter值做了++操作,因此最终展示出来的效果递增+1。

其实flutter和react-native类似,采用的是单向数据流,关于flutter的数据流管理、状态管理我们将在后面的文章里重点介绍。