Flutter 学习第四天 第一个flutter项目

这个转自我自己的有道云 想看图片去那里

文档:Day2_26 Dart 面向对象 异步语法.md
链接:http://note.youdao.com/noteshare?id=1dc3ee54f0ddd36e174d4b2aff0b65c9

第一个flutter项目

注意: 这篇笔记只是让你了解一下大致的flutter项目的创建过程 并不是让你都会

1.创建第一个flutter项目

我们可以选择多种方式创建flutter项目, 一个是可以使用IDE自带的创建flutter项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8fJv7jtn-1583059963619)(https://note.youdao.com/yws/res/66600/5FE82DCC1578436D990D7969CF4EC35C)]

但是这种创建都会产生一些莫名其妙的文件, 所以老师一般还是喜欢自己创建flutter

这里我们直接通过终端来创建flutter项目, 工具创建的话很简单 一直下一步就可以了

1.1 使用命令行创建flutter项目

进入到对应的文件夹下面 使用下面的命名就可以创建flutter项目

  • 创建的项目名 注意不要有标点符号(项目里面不要包含特殊符号
  • )
  • 但是可以使用_来隔开单词
  • 同时不能使用大小写的方法 驼峰命名法不能使用(要隔开的话就使用_)
    flutter create learn_flutter(创建的项目名)
  • 出现这个界面的时候其实项目还没有创建完成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fQVxw5Xh-1583059963620)(https://note.youdao.com/yws/res/66621/A73E161DF49C4FD2A68F7284B3E583CB)]

  • 这样才算创建成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cflxogVs-1583059963621)(https://note.youdao.com/yws/res/66626/D6A2FFDE30E342CB85453CCE272FA191)]

1.3 创建成功后

这个时候它其实已经提示你了

  • 如果你想运行你的项目的话我们可以cd到对应的目录下面
  • flutter run 运行你的项目

但是我们要开发这个项目, 所以我们不能这样

1.3.2选择工具打开项目

我们这里有两个工具可以选择

  1. vscode
  2. Android Studio
  • 前面在学dart我们用的是vscode
  • 但是我们在学flutter的时候我们就用的是Android Studio

这个是因为Android的功能要强一些

  • 虽然它重(占用的内存多)
  • 但是它集成性要强很多, 而且它提供很多对flutter的支持 和 vsode一样

1.3.3 使用Android 打开项目

我们可以这样打开这个项目, 当然你如果有项目在打开 我们可以点击菜单里面的文件 打开就可以打开对应的项目了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eR63vpao-1583059963622)(https://note.youdao.com/yws/res/66662/9C1309F727C649B9BD92F39A37F564F8)]

打开的flutter项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A4Ra4HzW-1583059963623)(https://note.youdao.com/yws/res/66667/303D58D0557F4596AA085F02CB3B847D)]

  • 但是如果你的Android Studio 没有创建一个flutter项目这个选项, 有很大概率是你没有装flutter Dart 插件
  • 前面我们讲过如果我们要在Android Studio上面运行Dart和flutter 我们需要下载两个插件

怎么打开呢

我们打开file -> 打开setting -> 点击Plugines

然后搜索Dart, Flutter下载了才行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3AOqnBS7-1583059963624)(https://note.youdao.com/yws/res/66682/48E6952DDBE34DEE8519C67EBC4C0D72)]

2. flutter项目的目录结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEqqWYlC-1583059963624)(https://note.youdao.com/yws/res/66693/8325D6387EEE4814BCAF6A10532C596D)]

2.1 文件介绍

2.1.1 .dart_tool

依赖第三方库的一些基本信息

  • 这个东西不要手动去配, 所以也不要去修改它

这个也是之前dart我们说过如果我们使用了第三方的库, 它就会自动的生成的东西

这个东西其实记录着一些东西所在的位置

2.1.2 .idea .iml文件也是一样的

这个Android Studio是Google基于idea开发的 所以它也有这个文件

这样做了之后Android Studio就免费了, 因为IDEA是收费的

如果你之前使用过这个公司的IDEA, 它一般创建的项目都有这个文件

这个东西是记录着你项目的一些配置

learn_flutter.iml 这个是记录一些项目信息的文件, 这两个文件都没有什么好说的啊

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DRoOuD1l-1583059963625)(https://note.youdao.com/yws/res/66726/ECFC7A4052664538842E45888AE96BE6)]

2.1.3 android文件夹

这个里面android文件夹里面是对应的android文件

因为我们的flutter项目开发完以后它是可以作为一个Android单独跑起来的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujJXJlHf-1583059963625)(https://note.youdao.com/yws/res/66737/ADA01CA930604EB9B4DEB9000150CAEB)]

如果你比较熟悉Androd的话 这个文件其实就是一个Android工程

2.1.4 ios文件夹

ios 是对应的ios文件

2.1.5 lib文件夹

lib里面是对应的dart的源代码 我们以后写的所有的代码都是写在这个里面 lib

里面的main.dart 是启动的入口函数 这个名字不能改

2.1.6 test文件夹

test文件里面是一些测试的文件 也比较重要

2.1.7 .gitignore

里面是上传到git忽略的东西, 和vue项目的哪个东西是一样的

它基本已经帮我们配好了, 一般情况下是不需要做手动配置的

2.1.8 .metadata

它是flutter版本的文件 不要更改它

2.1.9 pubspec.yaml

里面是package.json一样对应的东西

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FbExnsDp-1583059963626)(https://note.youdao.com/yws/res/66767/F42BF50285804E479152513272AC07CF)]

我们当时还写过 name description depandencies

dart做库管理用的东西(基本等价于package.json的作用)

下面的这些都是做库管理的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5hlqBZKt-1583059963627)(https://note.youdao.com/yws/res/66762/EF056CDCF9AA4446B68B87DB0D4CB607)]

2.1.10 README.md

README是对应的提示文件

3. 运行项目

我们需要将项目运行到模拟器上面来看一下

  • 运行的时候: 保证你的模拟器是打开的状态, 如果不清楚运行环境是否都安好了, 可以去终端上输入

flutter -doctor 来检测一下 或者直接看一下这个地方, 如果显示的差不多 说明你环境是对的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TIfsJ2Oi-1583059963627)(https://note.youdao.com/yws/res/66788/BC1FE3F7479644488157E16B05506BCC)]

然后我们点击

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vUuaGINb-1583059963628)(https://note.youdao.com/yws/res/66790/71E6305A8CFE43F88A76F1195518CB32)]

在flutter开发中有两个经常用的, 一个叫热重载, 一个叫热重启

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WmRMzLx2-1583059963628)(https://note.youdao.com/yws/res/66444/CAD2D64E36124A7482226C3FF110B673)]

启动项目中。。。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YvofJSQP-1583059963629)(https://note.youdao.com/yws/res/66439/18DA4F222F2E47E08DA1F440722E2500)]

它这个项目就是一个计数器的功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZCd6Ul2k-1583059963629)(https://note.youdao.com/yws/res/66799/EB07DF5500D842D296A3FAC37711D941)]

3.1 冷启动, hot-reload 和 hot-restart

其实我们运行一个flutter项目

  1. 冷启动(从零启动) 这个启动过程非常慢(1m - 5m)
  2. 热更新 当前项目已经启动起来了 然后你变了一点东西 它会更新后快速重启(hot ) 最主要是执行build 方法 改变里面的代码但是里面的数值是不会变的
  3. 热重启 会全部重新初始化

当我们的项目已经启动起来了我们就可以使用热启动了

  • 如果我们想要修改了东西, 想要马上看到效果
  • 我们就可以使用热启动

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ty0MLg0E-1583059963630)(https://note.youdao.com/yws/res/66826/B8CBF45261554B86B9BC9195ED89C4E0)]

我们把这里的颜色改掉, 然后我们想要看到效果, 但是如果我们还是像之前一样使用冷启动的话我们就需要花费很多的时间

这也是我们之前在进行android/ios开发的时候经常遇到的问题

  • 可以使用热重载来快速重载我们的改动
  • 但是这个热重载虽然重载的快但是它是重新执行的build方法[不清楚这里也没有事] 所以有些方法它是不会执行的

如果我们使用热重启

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qkjxTjDd-1583059963630)(http://note.youdao.com/yws/res/66858/WEBRESOURCE4ec7631b5e061426a53c76aa2ce04c26)]

我们发现这个计数器清零了

之前说过了, 如果使用的热重载它是只会执行重新build方法

但是如果是热启动的话他是会整个的重启执行app的

我们全部重新写

入口函数dart 要有main函数

然后就是我们需要运行App函数 runApp函数

这个函数要传入一个Widget 在flutter开发里面认为万物都是Widget

但是这个东西它是一个抽象类, 抽象类不能实例化, 所以我们需要传入一个子类对象我们这样传入对应的参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ExKY3WDK-1583059963631)(https://note.youdao.com/yws/res/66488/DFCCFE23ADA046DEA7A31AA1436CA82A)]

正式开始flutter代码

  • 老师说过了, 我们的写的代码都是直接放在lib中的

然后我们的lib中只有一个main.dart 文件 这个文件就是入口文件

他启动的时候就会去找这个文件, 找到这个文件之后运行什么文件呢

我们现在作为初学者肯定看不懂, 那么我们把这个里面的代码全部删掉

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KpAoV5An-1583059963631)(http://note.youdao.com/yws/res/66893/WEBRESOURCE50eee981abb9f836c245160ad028979e)]

看下它报了什么错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQ1ZOjrT-1583059963632)(http://note.youdao.com/yws/res/66900/WEBRESOURCEe5566419f5cfdb910bc33b482bacef22)]

它说你找不到配置文件

然后就是我们因该知道dart代码的入口是mian函数

所以我们至少因该把main代码写出来

main(List args) {

}

我们这里也可以给它传过来参数的, 但是flutter这里其实是没有传过来参数的

那么这些东西可以省略掉

这意味着我们flutter在运行项目的时候就是运行的我们的main函数

那么我们因该在里面写什么东西呢

  • 这里我们就要调用函数runApp

这个是一个全局函数, 这个是一个flutter内置的函数

但是我们当前是没有这个函数的, 所以这个时候我们需要导入一个库

它这个东西是属于一个package

import 'package:flutter/cupertino.dart';

main() {
  // 1. runApp函数
  runApp(app)
}

然后为了能理解原理我们点到对应源码的地方

flutter是开源的, 所以我们能够看到它的源码

按住ctrl + 左键 就是点进去到源码里面

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

我们看到它传了一个东西, Widget

这个东西在flutter里面非常的重要

  • flutter有个概念就是万物都是Widget

所有的东西都是Widget[google: 部件]

它和万物且对象是不一样的, 那个是一个大的方面

在万物都是对象的前提下面, 小一点的范围万物都是Widget

那么他既然需要一个Widget, 那我们传入一个Widget就可以了啊

但是不行 这个Widget他是一个抽象类

@immutable
abstract class Widget extends DiagnosticableTree {
  /// Initializes [key] for subclasses.
  const Widget({ this.key });

抽象类不能直接实例化, 但是我们可以实例化它的子类

所以我们这里需要传入一个子类

所以我们这里就传入Text 这个是它的子类

怎么看呢

一样点进去

class Text extends StatelessWidget {

然后再点击 StatelessWidget, 这个东西继承至Widget

abstract class StatelessWidget extends Widget {
  /// Initializes [key] for subclasses.

要求父类但是传入了一个子类, 这个就是我们的多态

import 'package:flutter/cupertino.dart';

main() {
  // 1. runApp函数
  runApp(Text());
}

我们这里其实是

import 'package:flutter/cupertino.dart';

main() {
  // 1. runApp函数
  runApp(new Text());
}

虽然没有new 但是你要知道这个地方他不是一个函数

父类引用指向子类对象, 这里可能会很细啊

这个是希望能理解源码, 这样我们就不需要记了

我们只要经常读它的代码很多东西你就不需要记了

然后我们发现这个代码报错了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-roXQoSCl-1583059963633)(http://note.youdao.com/yws/res/67047/WEBRESOURCE6a406a0fdd90ddbf64b3da04aa333266)]

报错的意思也很清楚, 我们点进去看一下源码

class Text extends StatelessWidget {
  /// Creates a text widget.
  ///
  /// If the [style] argument is null, the text will use the style from the
  /// closest enclosing [DefaultTextStyle].
  ///
  /// The [data] parameter must not be null.
  const Text(
    this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    ...

我们发现这个Text, 它有一个必传参数, 不传就会报错

  • 很多东西不容易记住的, 所以这个时候我们就可以直接看源码
  • 所以我们也要掌握dart语法

后面的参数是命名可选参数, 需要将变量的值做进去

import 'package:flutter/cupertino.dart';

main() {
  // 1. runApp函数
  runApp(Text("hello world"));
}

这样的话我们的第一个flutter项目就写完了

像我们的flutter项目的就完成了

但是我们现在最好直接关了重新启动一次

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q3PJSA1n-1583059963633)(http://note.youdao.com/yws/res/67076/WEBRESOURCE6780462cd40f9b7dda2102f5c0289f8f)]

然后再启动一次, 但是这个是很慢的

因为它是冷启动, 他需要重新加载我们的flutter框架, 他会重新找到我们的开发工具

比如xcode 然后对他进行一个重新打包, 他是这样一个过程

然后我们就看到它报错了

  • 然后就是希望能够看懂这个报错的信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1EQEvcoi-1583059963634)(http://note.youdao.com/yws/res/67092/WEBRESOURCE9d8f72c0b788900dc2dc5dbf7f51aa06)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TnCDDLpC-1583059963634)(https://note.youdao.com/yws/res/66493/CAF1AFDEDC4944EABA16D461A0B09254)]

它里面说 这个Widget没有方向

  • 这个是我们必须传一个排版的方向

但是排版方向这个东西不是很明显的事情吗

从左到右, 从上到下

这个是因为 flutter这个框架并不是面向我们中国人使用的, 也不是面向使用英语的国家使用的

他是面向全球的开发者使用的, 他们就考虑到了有些国家语言就是从右到左

所以这里设置了一个报错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7Zf4obp-1583059963635)(http://note.youdao.com/yws/res/67118/WEBRESOURCEea8aeeec59c87a0de085da024a7e017b)]

它是一个命名可选参数

他是一个textDirection 的类型

  • 构造函数首字母全部大写
  • 普通函数方法大写

我们再来看下这个textDirection该怎么传

这个东西就是一个枚举类型

enum TextDirection {
  /// The text flows from right to left (e.g. Arabic, Hebrew).
  rtl,
  /// The text flows from left to right (e.g., English, French).
  ltr,
}

很明显这个ltr就是从左到右, 而这个rtl就是从右到左

所以这个值很明显就该这么 TextDirection.ltr 来传

import 'package:flutter/cupertino.dart';

main() {
  // 1. runApp函数
  runApp(Text("hello world", textDirection: TextDirection.ltr));
}

我们再来热重载一次

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sfPLD5Fc-1583059963636)(http://note.youdao.com/yws/res/67153/WEBRESOURCE9d9be055ec9172b15c87130f2ce7d70c)]

这样我们就有结果了

但是为什么这个既然一定需要但是却不搞成必选 原因就是
material风格的Widget它会自动的传一个ltr 进来

这个时候我们就可以不用传这个参数了, 所以它不是必选的

然后就是这样看起来太长了

  • 所以这里建议使用这种代码风格

这里写开了方便看

import 'package:flutter/cupertino.dart';

main() {
  // 1. runApp函数
  runApp(
      Text(
          "hello world",
          textDirection: TextDirection.ltr
      )
  );
}

写代码时候 要求要两个空格的缩进

虽然也可以使用四个空格的缩进但是不建议这样用

然后就是这个东西看起来有点太小了

所以我们希望它的字体大一点, 这里我们可以给他添加一个属性style

这个style是Text的命名可选参数

  const Text(
    this.data, {
    Key key,
    this.style,
    this.strutStyle,
    this.textAlign,
    ...

这个东西对应的一个类型是TextStyle类型

然后一直点进去就发现这个东西有很多的有关字体的属性

@immutable
class TextStyle extends Diagnosticable {
  /// Creates a text style.
  ///
  /// The `package` argument must be non-null if the font family is defined in a
  /// package. It is combined with the `fontFamily` argument to set the
  /// [fontFamily] property.
  const TextStyle({
    this.inherit = true,
    this.color,
    this.backgroundColor,
    this.fontSize,
    this.fontWeight,
    this.fontStyle,
    this.letterSpacing,
    this.wordSpacing,
    this.textBaseline,
    this.height,
    this.locale,
    this.foreground,
    this.background,
    ...

color又是一个枚举类型

它的定义很多的颜色, 这里我们就讲怎么用

Colors.red 就可以取到对应的值

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      Text(
          "hello world",
          textDirection: TextDirection.ltr,
          style: TextStyle(
            fontSize: 30,
            color: Colors.red
          )
      )
  );
}

但是直接刷新是看不到东西的

因为热重载是只重新执行build方法

所以这些方法它并不会执行 要热重启才行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FeoA6oDC-1583059963636)(http://note.youdao.com/yws/res/67223/WEBRESOURCE577f19569f1ca300b5db8f39308a9994)]

成功了

然后就是我们希望我们能将文字居中

如果你在其他的地方做一些开发的话, 他可能有有些属性可以让你的文字居中, 但是你在你的flutter中不是这样做的

如果你希望你在你的组件中居中的话你就要这样做(万物皆是Widget 居中也是)

我们剪掉我们的runApp中的内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2AOux6A2-1583059963637)(https://note.youdao.com/yws/res/66499/339279271CC142A4BE87495D563D8633)]

然后将我们剪掉的部分

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      Center(
        child: Text(
            "hello world",
            textDirection: TextDirection.ltr,
            style: TextStyle(
                fontSize: 30,
                color: Colors.red
            )
        ),
      )
  );
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-14Vt3lMr-1583059963637)(http://note.youdao.com/yws/res/67248/WEBRESOURCEfb94b1ff5983a47e26b3d260f11988c9)]

我们也可以通过Widget居中, 甚至可以通过Widget 来设置padding 透明度等

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGONdyh0-1583059963638)(https://note.youdao.com/yws/res/66506/B41E067E4EF44E3294D816638D6D4C1E)]

所以在flutter中我们是通过这个Center来做的居中

  • Flutter中万物皆是Widget

但是如果你是Android或者是IOS过度过来你就会非常的 不适应

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OupQY2EM-1583059963638)(https://note.youdao.com/yws/res/66518/09ECD00716114D57934CEF65A5F04AFC)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V7W7caiW-1583059963639)(https://note.youdao.com/yws/res/66520/D9C24AD3FF564827B6DB481C59FEF50A)]

然后我们的第一个app就算开发完了, 一般情况下一个app会包含一些特别的

我们现在想要它有导航的功能所以 NaBar那种东西

Widget的翻译

  • Widget在国内有很多的翻译
  • 做Android, IOS开发的, 喜欢将它翻译成控件
  • 做过Vue, React 等开发的人群, 喜欢将他翻译成组件
  • 如果我们使用Google, Widget翻译过来因该是小部件

一般我们更倾向小部件组件

如果你从其他的开发比如Android转过来

Android它就有很多的控件: Button, ImageView, Activtiy => Widget[这些东西在Flutter中通通都是Widget]

IOS也是: UIViewController UIView UiButton 但是在flutter中都是Widget

  • vue中这种做法的东西通常叫做组件

如何开发一个正常的app呢

一般的app肯定不会像现在的这个东西一样一个光棍

至少因该要有这些东西

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fPrPd8Ij-1583059963639)(http://note.youdao.com/yws/res/67277/WEBRESOURCEf09b20db430312bb71c95cc39ca85130)]

这样我们就可以使用Material风格的东西

Material

  • Material是一种google公司推行的一种设计风格(也可以叫做设计语言, 设计规范)
  • 里面有很多的设计规范, 比如颜色, 文字的排版, 相应动画的过度, 填充等
  • 在Flutter里面高度集成了 Material风格的Widget
  • 在我们的应用中, 我们就可以直接使用这些Widget来创建我们的引用(后面会用到很多)

我们看一下源码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i8Kb2LN7-1583059963640)(http://note.youdao.com/yws/res/67359/WEBRESOURCEd1bb78583143dfc3bc9214037a2d54e2)]

我们可以看到Material这个东西继承至StatefulWidget

而这个东西又继承自Widget

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eCU9iRmM-1583059963640)(http://note.youdao.com/yws/res/67361/WEBRESOURCE0081c35feee0544b73b47f59e5939750)]

那么我们就在这里使用这个

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
      )
  );
}

而这个东西有个命名可选参数home

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DojUhxJm-1583059963641)(http://note.youdao.com/yws/res/67371/WEBRESOURCEbe662dcf0d1fa4fb7f7697212793e0e8)]

然后我们把之前剪掉的东西放进来

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        home: Center(
          child: Text(
              "hello world",
              textDirection: TextDirection.ltr,
              style: TextStyle(
                  fontSize: 30,
                  color: Colors.red
              )
          ),
        ),
      )
  );
}

这样的话我们使用这个Material有些东西就不需要去设置了

比如Material中文字的排版, 它的排版方式就是从左往右进行排版的, 所以这个textDirection 就可以删掉了

import 'package:flutter/material.dart';

main() {
 // 1. runApp函数
 runApp(
     MaterialApp(
       home: Center(
         child: Text(
             "hello world",
             style: TextStyle(
                 fontSize: 30,
                 color: Colors.red
             )
         ),
       ),
     )
 );
}

热重启以后就会看到

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UZyH1nNb-1583059963641)(http://note.youdao.com/yws/res/67390/WEBRESOURCE0db922c84d8ab5d4726ca3f828314b2b)]

它会默认的增加一下东西, 这个下划线也就是默认加上去的

但是这个也不是我们想要的结果

添加NavBar

Material这个东西除了作用是保持我们的这个页面是Material风格的

如果我们想让我们的东西有导航的功能, 可能还要有tabBar这些东西的话, 这个使用我们就要对这个东西再进行一个嵌套

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        home: Scaffold(
          
        )
      )
  );
}

这个Scaffold叫做脚手架, 它最主要的作用是帮助我们快速的搭建页面

仔细说来就是如果你现在要做一个导航, 那你可能还要对上面的东西做一个适配的, 这个就麻烦了

所以它这里就给你提供了一个脚手架,来让你可以快速的搭建这个页面

那它这里有什么参数呢

Scafford使用

这里最常见的是两个参数

一个是appBar, 另外一个body 而这里展示的这个东西就是body

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        home: Scaffold(
          appBar: ,
          body:
        )
      )
  );
}

分不清逗号分号

有些时候可能不容易分清

  • 一条语句结束之后写分号
  • 传的属性之间的是逗号
main() {
  Person(
      name: "why",
      age: 10
  );
}

class Person {
  String name;
  int age;

  Person({String name = "why", int age = 10 });
}

然后现在就还有一个东西没有传了 appBar

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        home: Scaffold(
          appBar: ,
          body: Center(
            child: Text(
                "hello world",
                style: TextStyle(
                    fontSize: 30,
                    color: Colors.red
                )
            ),
          ),
        )
      )
  );
}

我们点进去看看

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bsh3nRgl-1583059963641)(http://note.youdao.com/yws/res/67463/WEBRESOURCE987bddfe32eea288d024b854b947dfc0)]

我们发现这个PerferredSizeWidget是一个抽象类

那我们还是只能使用它的子类

使用appBar

我们一般是使用他的AppBar和TabBar两个子类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLoZDfEY-1583059963642)(http://note.youdao.com/yws/res/67473/WEBRESOURCE5d490735ace757c58c5fe9bc9e4ec4bc)]

我们现在是需要NavBar这种东西, 那就以为着我们这里需要传东西的时候是传的AppBar

一定要学会看源码

    1. 一定要学会看源码, 忘的时候看源码就可以了
    1. 可以帮助你理解这个Flutter的结构

这个AppBar它一般有个参数 title 这个东西就是标题

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: ,
          ),
          body: Center(
            child: Text(
                "hello world",
                style: TextStyle(
                    fontSize: 30,
                    color: Colors.red
                )
            ),
          ),
        )
      )
  );
}

那这个参数是什么呢

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JKviEZlq-1583059963643)(http://note.youdao.com/yws/res/67492/WEBRESOURCEe81a879d6edafbdb0c7ea306c319c281)]

它是一个Widget 那这里以后我们会详细讲的 我们这里就使用Text

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text("第一个Flutter程序"),
          ),
          body: Center(
            child: Text(
                "hello world",
                style: TextStyle(
                    fontSize: 30,
                    color: Colors.red
                )
            ),
          ),
        )
      )
  );
}

这个时候我们使用hot-reload是不行的, 我们用hot-restart 就。。。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JvCvB42N-1583059963644)(http://note.youdao.com/yws/res/67508/WEBRESOURCEa65a3dfb61ebceaa717b24566a67aa1e)]

这样你就会发现我们要开发的第一个flutter应用程序 就已经开发完成了

我们想要的其实也就是这个效果

我们也可以让右上角的东西消失

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(
      MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(
            title: Text("第一个Flutter程序"),
          ),
          body: Center(
            child: Text(
                "hello world",
                style: TextStyle(
                    fontSize: 30,
                    color: Colors.red
                )
            ),
          ),
        )
      )
  );
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aHdeypQU-1583059963644)(http://note.youdao.com/yws/res/67525/WEBRESOURCE06bc279b9e94df66a4ed4b7070cd906a)]

  • 注意: dart是一个真正面向对象的语言, 所以double这些变量都是对象

代码嵌套过多

现在我们的代码嵌套的太多了, 我们可以把它封装起来, 让它好看一点

把我们的这段东西啊拆成一段小的Widget, 然后再让他合体

runApp的时候他要求我们传的必须是一个Widget

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jWSYVBSY-1583059963645)(https://note.youdao.com/yws/res/66539/83681682D5D14C6D996204A1D2EBF813)]

我们可以创建类 然后让它成为Widget再传进去, 就可以做分离的工作了

然后命名前面加东西来区分自己创建的类和原生的东西

HY+命名的名

class HYHomePage {
  
}

我们想要创建一个Widget那我们 extends来试一试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-alWhCbdo-1583059963645)(https://note.youdao.com/yws/res/66549/037F6377B57A4003B6725D543F40DD6C)]

因为我们继承了Widget, 所以我们需要重写里面的所有的抽象方法

这个时候它要我们重写一个方法, createElement 但是这样写涉及到底层, 我们没有必要这样写代码

我们所有的Widget最后是通过element进行渲染的, cretaeElement 就会涉及到flutter的底层了

Widget 的分类

所以我们不能使用, 我们就可以使用Widget的子类来让他实现

Widget:

  • 有状态的Widget: StatefulWidget 在运行过程中有变量(状态)要改变的
  • 无状态的Widget: StatelessWidget 内容是无状态(data)改变

在我们真实的开发环境下面不要直接使用Widget, 这样我们写代码不好写, 所以我们这里就使用StatelessWidget

因为我们这里没有变换的变量, 所以直接继承至StatelessWidget就可以了

class HYHomePage extends StatelessWidget {

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RcQ3cmGF-1583059963646)(https://note.youdao.com/yws/res/66559/A9308688920348F1A27E3FD413B39945)]

但是我们发现这里依旧报错

这个是因为StatelessWidget它也有一个抽象方法, 也需要在这里被实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zDAOeCyq-1583059963646)(http://note.youdao.com/yws/res/67590/WEBRESOURCEa9c516ba0e5b10ed41d8cbc5e4c13c77)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aKO0LXdI-1583059963647)(http://note.youdao.com/yws/res/67592/WEBRESOURCE08e80f81d94408df83440f849b5bcb67)]

这个方法叫做build方法

  • build方法就是告诉flutter我的这个自定义的方法里面到底要渲染什么内容

假如说你这里返回一个Text() 你就告诉flutter这里我们是需要渲染一个文字

class HYHomePage extends StatelessWidget {
//  build方法
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Text("hello flutter");
  }
}
  • 以widget 为核心它就是一个树的结构

  • 这个也是flutter的组件化

  • build方法什么时候执行呢

      1. 当我们的StatelessWidget第一次被插入到Widget树中的时候(也就是第一次被创建的时候)
      • flutter构建完整的时候他其实是一个Widget树, 当它插入到树里面的时候这个方法就会被自动调用一次
      1. 当我们的父Widget(parent widget)发生改变的时候, 子Widget会被重新构建
      1. 如果我们的Widget依赖的InheritedWidget的一些数据, InheritedWidget数据发生改变的时候

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzT23gYx-1583059963647)(https://note.youdao.com/yws/res/66564/5D89769ED9824A7D8CF906379D9C271D)]

这些东西先不急当到状态管理的时候我们再仔细讲

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BmTdNHGq-1583059963648)(https://note.youdao.com/yws/res/66562/6D4F118343D14A40963508EC6F0720F9)]

那我们现在将这里的代码全部剪掉

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7nxAmWcA-1583059963648)(http://note.youdao.com/yws/res/67641/WEBRESOURCE84e4a147d3d60e85fb373c82a82916a2)]

我们就可以把它这样, 放到我们的自定义的Widget中

这样我们的main函数就只有一行代码

import 'package:flutter/material.dart';

main() {
  // 1. runApp函数
  runApp(HYHomePage());
}


class HYHomePage extends StatelessWidget {
//  build方法
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(
            title: Text("第一个Flutter程序"),
          ),
          body: Center(
            child: Text(
                "hello world",
                style: TextStyle(
                    fontSize: 30,
                    color: Colors.red
                )
            ),
          ),
        )
    );
  }
}


我们就可以把它变成这样 就是使用箭头函数的语法

main() {
  runApp(HYHomePage());
}

=>

main() => runApp(HYHomePage());

抽取分离[组件化]

我们发现这个代码还是有点多

那我们就继续抽离

import 'package:flutter/material.dart';

main() => runApp(HYApp());


class HYApp extends StatelessWidget {
//  build方法
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: HYHomePage()
    );
  }
}

class HYHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("第一个Flutter程序"),
      ),
      body: HYCenter()
    );
  }
}

class HYCenter extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: Text(
          "hello world",
          style: TextStyle(
              fontSize: 30,
              color: Colors.red
          )
      ),
    );
  }
}


依然是没有报错的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p92GpmTC-1583059963649)(http://note.youdao.com/yws/res/67674/WEBRESOURCE74d805354c5e7ef49d7f4a166f5dd9ca)]

这样我们就出现了一个树形结构, 组件化的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GuA0z6zj-1583059963649)(http://note.youdao.com/yws/res/67679/WEBRESOURCEbf8b396192c48fe69048eb449ab34be1)]

  • React, Vue: 样式和结构进行分离[这样做有好处也有坏处]
    • 好处就是: 分开了之后代码格式比较清晰
    • 坏处就是: 写在多个地方
  • flutter: 就是将这个东西写在一起
  • 而且你如果将代码组织的比较合理的这个代码结构还是比较清晰的
  • 而且随着开发的深入 肯定还是将代码放到不同的文件里面去

把代码写规范就好看了

这个就是将我们的代码进行了一个重构, 后面我们规划好就不需要重构

你可能感兴趣的:(dart,flutter,flutter)