Flutter学习指南:编写第一个Flutter应用

345 阅读7分钟

本文由 爱学园平台 进行联合编辑整理输出

原作者:爱学园——莫比乌斯环

这是 Flutter 系列文章的第二篇,关于 Flutter 的相关学习文章后面还有很多,如果您喜欢的话,请持续关注 ,谢谢!

Flutter 是 Google 推出的移动端跨平台开发框架,使用的编程语言是Dart,是继 React Native 之后开发者对跨平台解决方案的又一探索,追其根源,本质上以移动端的统一为走向,缩短人力、物力、时间!这是开发者、企业的共同目标。本篇我们以一个简单的 Flutter 应用,为大家讲解 Flutter 应用的开发流程。

我们本篇的主旨是让用户对 Flutter 应用的创建、调试、打包、安装等过程有一个直观的认识。在大家的记忆中是不是学习一门语言,都是以 Hello World 开始的,Flutter 也不例外,今天我们以一个 Hello Flutter 应用开启我们的第一次~,界面非常简单,主要就是界面上展示一个计数器,随着用户的点击累加。

创建工程

在创建项目之前,你需要配置开发环境,如果你还没有完成此操作,请移步开发环境搭建,如果已完成,请跳过,这里我们通过Android Studio编译器来创建工程。

  1. 选择 File>New Flutter Project
  2. 选择 Flutter application 作为 project 类型, 然后点击 Next
  3. 输入项目名称 (如 flutter-app),存储路径,Flutter SDK 路径选择, 然后点击 Next
  4. 创建包名(小写、字母、数字、下划线),点击Finish
  5. 等待 Android Studio 创建项目(第一次可能需要点时间)

1.工程目录结构

工程目录结构

  1. android Android 平台相关代码
  2. ios IOS 平台相关代码
  3. build 项目编译产生的目录,此时不需要关心(后期编译的安装包输出在该目录下)
  4. lib 跨平台代码,也是 Flutter 项目主要关心的目录
  5. test 测试相关代码
  6. pubspec.yaml 项目描述文件,相当于 NodeJs 项目的 package.json,里面包含了项目的描述信息以及所需要的依赖的库

2.Flutter工程入口文件——lib/main.dart

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
        body: new Center(
          child: new Text('Hello Flutter'),
        ),
      ),
    );,
    );
  }
}

3.运行上述代码,效果如下:

Hello Flutter

分析

  • 默认示例创建一个Material APP。Material是一种标准的移动端和web端的视觉设计语言。Flutter提供了一套丰富的Material widgets。
  • main 函数(执行入口)使用了(=>)符号,这是Dart中单行函数或方法的简写。
  • 该应用程序继承 StatelessWidget ,这说明应用本身也是一个 Widget
  • Scaffold 是Material library中提供的一个widget,它提供了默认的导航栏、标题和包含主屏幕widget树的body属性。
  • 从上可以看出Widget的主要工作是提供一个build()方法来描述如何根据其他较低级别的widget来显示自己。
  • 本事例中的body的widget树中包含了一个Center widget,Center widget又包含了一个Text子widget。Center widget可以将其子widget树对齐到屏幕中心。

修改工程

修改工程使其按照我们的设想变更,在屏幕上添加一个展示文本控件和一个可点击按钮,因此我们需要按照如下步骤修改入口文件:lib/main.dart

1.添加一个有状态的部件(Stateful widget)

这里我们需要明白以下几个概念:

  • Stateless widgets 是不可变的,这意味着它们的属性不能改变--所有的值都是最终的。
  • Stateful widgets 持有的状态可能在widget生命周期中发生变化。实现一个stateful widget至少需要两个类:
    1. 一个StatefulWidget类。
    2. 一个State类。StatefulWidget类本身是不可变的,但是 State 类在widget生命周期中始终存在。

在这一步,添加一个有状态的widget--MyHomePage,它创建其State类_MyHomePageState。这里我们将MyHomePage作为一个widget添加到现有的无状态widget--MyApp内部。

  1. 创建一个State类,添加到main.dart的底部:

    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      // This widget is the home page of your application. It is stateful, meaning
      // that it has a State object (defined below) that contains fields that affect
      // how it looks.
    
      // This class is the configuration for the state. It holds the values (in this
      // case the title) provided by the parent (in this case the App widget) and
      // used by the build method of the State. Fields in a Widget subclass are
      // always marked "final".
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
  2. 添加 _MyHomePageState 类,该应用程序的大部分逻辑和状态管理代码都在该类中,这个类保存屏幕上用户点击的次数,随着用户的点击,次数不断增加,且展示在界面上,代码如下:

    class _MyHomePageState extends State<MyHomePage> {
    	int _counter = 0;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      Widget build(BuildContext context) { 
        return new Scaffold(
          appBar: new AppBar(
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text(
                  'You have pushed the button this many times:',
                ),
                new Text(
                  "$_counter",
                  style: Theme.of(context).textTheme.display1,
                ),
              ],
            ),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: new Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
  3. 替换MyApp中的build方法内部home参数为新定义的MyHomePage widget,代码如下:

    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Welcome to Flutter',
          theme: new ThemeData(
        primarySwatch: Colors.green,//变更主题样式
      ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
  4. 重启应用程序。模拟器上的行为应该变更如下,展示一个计数器和按钮,点击按钮,文本计数增加(这里样式做了下调整),效果如下:

    demo

  5. 修改界面代码,样式,保存后界面数字并没有从零开始,这说明热重载与重启的区别,它只是单纯的改变相应的变化,State的状态会持续保存。

到此我们应用就改造完毕!代码很简单,我们这里主要想让读者明白的是创建一个Flutter应用的流程、组成部分和一些简单配置。

调试(debug)

一种采用debug模式调试,停止当前应用,点击顶部工具栏Debug main.dart 小按钮,启动应用,你可以在您需要监测代码处像原生一样打个断点,这里同原生并无两样,不做详细讲解。 另一种log日志输出方式调试:

debugPrint("message info ...")

这里只简单介绍下,不是本章的重点,此处不做详细分析,更多的调试方法读者可以根据需要查看https://flutter.io/debugging/ 进一步学习。

获取apk安装包

应用经过运行、测试,最后肯定需要安装到真机上,因此需要打包apk分发给用户使用。如下我们将分析Flutter如何进行项目打包(Android)。

  1. 查看android包下的清单配置文件AndroidManifest.xml。这是个模版生成文件,用户可根据需要进行修改;
  2. 构建文件build.gradle,这里同上一样也可做一些配置,比如说自动化签名配置,资源压缩,代码混淆配置等等;
  3. 启动图标的替换;
  4. 编译apk。执行如下命令flutter build apk,输出apk安装包到build/app/outputs/apk/release/app-release.apk;
  5. 安装,在根目录下执行flutter install就可以安装这个apk了。

总结

阅读完上述步骤我想您在下面几个方面会有深入的思考:

  1. 从头开始创建一个Flutter应用。
  2. 编写Dart代码。
  3. 使用热重载加快开发周期。
  4. 一个有状态的widget创建过程和概念。
  5. 如何打包和调试app

对于IOS的开发,读者可以看https://flutter.io/ios-release/,这里就不再详细描述了。好吧到这里您的第一个Flutter应用应该完成了吧。如果遇到问题可以留言我们一起讨论,谢谢!