Flutter 初学Flutter页面开发 一. 创建Flutter项目 二. 目录结构 三. hot reload & hot restart 四. flutter

一. 创建Flutter项目

1.1. 创建

命令行方式

flutter create learn_flutter

注意:

  • Flutter的名称不要包含特殊的字符,另外 <font color=red>不可以使用驼峰,不支持大写,尽量不要使用一些符号</font> 标识
  • 创建完之后使用自己喜欢的开发工具打开即可
  • xxx_xxx 下划线格式较多一些

工具创建

如:android studio - Start a new Flutter project

1.2. 运行

运行

  • 命令行方式,进入flutter项目目录:flutter run即可

  • android studio 打开项目,可以使用ide提供的快捷工具直接运行,as也是可以运行ios模拟器的

  • 也可以通过as或xcode分别打开flutter项目中的android或ios代码,直接运行即可。

  • as也可以直接打开整个flutter项目代码

断点

vscode dart代码支持断点调试的,也是代码面板左边点击某行代码打上断点,然后run - start debugging

二. 目录结构

文件或目录 说明
.dart_tool 记录了一些dart工具库所在的位置和信息
.idea android studio 是基于idea开发的,.idea 记录了项目的一些文件的变更记录
android Android项目文件夹
ios iOS项目文件夹
lib lib文件夹内存放我们的dart语音代码
test 用于存放我们的测试代码
.gitignore git忽略配置文件
.metadata IDE 用来记录某个 Flutter 项目属性的的隐藏文件
.packages pub 工具需要使用的,包含 package 依赖的 yaml 格式的文件
flutter_app.iml 工程文件的本地路径配置
pubspec.lock 当前项目依赖所生成的文件
pubspec.yaml 当前项目的一些配置文件,包括依赖的第三方库、图片资源文件等
README.md READEME文件

重要的文件就以下几个:

  • lib

我们日常开发的dart语言代码都放在这里,可以说是我们的“核心工作文件夹”

  • iOS

这里面包含了iOS项目相关的配置和文件,当我们的项目需要打包上线的时候,需要打开该文件内的Runner.xcworkspace文件进行编译和打包工作。

  • android

与ios文件夹一样,在android项目需要打包上架的时候,也需要使用此文件夹里面的文件。同样的如果我们需要原生代码的支持,原生代码也是放在这里。

  • test

这里存放了我们在项目开发过程中的测试代码,良好的测试习惯是保证代码质量的必要手段,希望大家在test文件里写更多的代码!

  • pubspec.yaml

就好比开发原生,你总要知道工程如何配置,依赖三方,资源文件等

2.1. main.dart

flutter 默认入口文件,内部main函数是flutter解析的入口

关于默认的main.dart文件:

1、程序默认入口文件,这个是可配置的,如as开发环境:可以通过Edti Configuratios来修改入口文件。。。也可以通过命令行:flutter run -t lib/entry.dart

2、虽然入口文件能修改,但是一般不用,并且注意,入口文件内必须有main函数主入口的,这个跟android,ios之类的一样

三. hot reload & hot restart

冷启动

从零编译运行,耗时

hot reload

主要执行build:

@override
  Widget build(BuildContext context) {

意思就是如果修改的是build方法体内的内容,只需要hot reload即可

hot restart

重新运行整个app,如果修改的是非build内容,则需要hot restart

四. flutter

4.1. 基本页面

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('title'),
        ),
        body: Center(
            child: Text(
              'hello world',
              style: TextStyle(
                  color: Colors.amber,
                  fontSize: 50
              ),
              strutStyle: StrutStyle(
                fontSize: 10,
                fontStyle: FontStyle.italic,
              ),
              textDirection: TextDirection.ltr,
              // textScaleFactor: 2,
            )
        ),
        bottomNavigationBar: BottomAppBar(
          color: Colors.red,
          child: Text(
            'bottom'
          ),
        ),
      )
    )
  );
}

4.2. 代码分析

runApp

runApp是Flutter内部提供的一个函数,当我们启动一个Flutter应用程序时就是从调用这个函数开始的

  • 我们可以点到runApp的源码,查看到该函数

该函数让我们传入一个东西:Widget?

widget

  • 我们学习Flutter,从一开始就可以有一个基本的认识:Flutter中万物皆Widget(万物皆可盘);
  • 在我们iOS或者Android开发中,我们的界面有很多种类的划分:应用(Application)、视图控制器(View Controller)、活动(Activity)、View(视图)、Button(按钮)等等;
  • 但是在Flutter中,这些东西都是不同的Widget而已;
  • 也就是我们整个应用程序中所看到的内容几乎都是Widget,甚至是内边距的设置,我们也需要使用一个叫Padding的Widget来做;

material

  • material是Google公司推行的一套设计风格,或者叫设计语言、设计规范等;
  • 里面有非常多的设计规范,比如颜色、文字的排版、响应动画与过度、填充等等;
  • 在Flutter中高度集成了Material风格的Widget;
  • 在我们的应用中,我们可以直接使用这些Widget来创建我们的应用(后面会用到很多);

cupertino.dart 风格

前端开发,ui是主要部分,上面的Material提供了丰富的ui组件,cupertino风格是苹果风格的,但不是很丰富,可以尝试用

Scaffold 脚手架

  • 翻译过来是脚手架,脚手架的作用就是搭建页面的基本结构;
  • 所以我们给MaterialApp的home属性传入了一个Scaffold对象,作为- 启动显示的Widget;
  • Scaffold也有一些属性,比如appBar和body;
  • appBar是用于设计导航栏的,我们传入了一个title属性;
  • body是页面的内容部分,我们传入了之前已经创建好的Center中包裹的一个Text的Widget;

4.3. 代码重构

一个简单的页面,嵌套写了那么多层的代码,很不友好,所以,正常的代码怎么做的?

flutter中万物皆widget,也即分析页面后,可以将页面元素拆分,比如:导航条,body体,底部视图等。然后各个部分抽离出来封装为新的组件

4.3.1. 封装widget

首先,新入门语言,都会觉得有些不是因,要做的是需要熟悉写法,学会该语言的代码结构,然后熟练就好了。

关于flutter的widget,先说明一下:

  • Flutter整个开发过程中就是形成一个Widget树,所以形成嵌套是很正常的。
  • 封装widget有两种类型,可以继承自StatelessWidget或者StatefulWidget

这里先不深入如何完全自定义widget,先学会小视图组合方式的封装,把代码重构清晰

4.3.1.1. StatelessWidget

StatelessWidget是没有状态改变的Widget,通常这种Widget仅仅是做一些展示工作而已;

  • 它们的数据通常是直接写死(放在Widget中的数据,必须被定义为final)
    • StatelessWidget所继承的Widget被@immutable标记,表示不可变,不可变是指该widget内所有的变量是不可变的,所以,你的widget内声明状态是不合理的。所以印证了上面的话:StatelessWidget类型的widget只做一些纯展示
  • 很重要的一点是:自定义widget内没有setState方法,所以,没法进行widget状态管理,触发重新渲染更新
  • 从parent widget中传入的而且一旦传入就不可以修改;
  • 从InheritedWidget获取来使用的数据;
//1、继承自StatelessWidget
//2、重写的方法:build方法
class MyStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return <返回我们的Widget要渲染的Widget,比如一个Text Widget>;
  }
}

build

  • Flutter在拿到我们自己创建的StatelessWidget时,就会执行它的build方法;
  • 我们需要在build方法中告诉Flutter,我们的Widget希望渲染什么元素,比如一个Text Widget;
  • StatelessWidget没办法主动去执行build方法,当我们使用的数据发生改变时,build方法会被重新执行;

build 什么情况会执行:

  • 1、当我们的StatelessWidget第一次被插入到Widget树中时(也就是第一次被创建时);
  • 2、当我们的父Widget(parent widget)发生改变时,子Widget会被重新构建;
  • 3、如果我们的Widget依赖InheritedWidget的一些数据,InheritedWidget数据发生改变时;

重构结果

篇幅原因,部分代码就不展示了

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: MyHomePage()
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('title'),
      ),
      body: HomeBody(),
      bottomNavigationBar: HomeBottomBar(),
    );
  }
}

class HomeBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Text(
          'hello world',
          ...
        )
    );
  }
}

class HomeBottomBar extends StatelessWidget {...}

4.3.1.2. StatefulWidget

StatefulWidget是需要保存状态,并且可能出现状态改变的Widget;前面说了,StatelessWidget是纯展示的一个widget,也即其是没办法做状态管理的,所以,其上内容是没法更新的。就做一些静态展示。。与其相对的额StatefulWidget就包含了状态管理,做数据展示和数据操作

StatefulWidget学习

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章