• 001flutter基础学习


    flutter基础学习

    参考:https://book.flutterchina.club/chapter1/flutter_intro.html

    • Flutter是谷歌的移动UI框架
    • 跨平台: Linux,Android, IOS,Fuchsia
    • 原生用户界面:它是原生的,让我们体验更好,性能更好
    • 开源免费:完全开源,可以进行商用
    • Flutter与主流框架的对比
      • Cordova`:混合式开发框架( Hybrid App)
      • RN ( React Native ) :生成原生APP ,但以View为基础嵌入
      • Flutter :在渲染技术上,选择了自己实现(GDI)
    • 生态环境
      • Google公司出品和推广并且在中国也有推广中心
      • 第三方组件也在迅猛发展https://github.com/Solido/awesome-flutter
      • 哪些公司已经在开始使用Alibaba Tencent JD
    • flutter能够达到20Fps超高性能

    fps:每秒传输帧数,可以简单理解为每秒画面数。

    flutter概述

    Flutter 是 Google推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用 Native引擎渲染视图,这无疑能为用户提供良好的体验。

    • 跨平台自绘引擎

    Flutter与用于构建移动应用程序的其它大多数框架不同,因为Flutter既不使用WebView,也不使用操作系统的原生控件。 相反,Flutter使用自己的高性能渲染引擎来绘制widget。这样不仅可以保证在Android和iOS上UI的一致性,而且也可以避免对原生控件依赖而带来的限制及高昂的维护成本。

    Flutter使用Skia作为其2D渲染引擎,Skia是Google的一个2D图形处理函数库,包含字型、坐标转换,以及点阵图都有高效能且简洁的表现,Skia是跨平台的,并提供了非常友好的API,目前Google Chrome浏览器和Android均采用Skia作为其绘图引擎。

    目前Flutter默认支持iOS、Android、Fuchsia(Google新的自研操作系统)三个移动平台。但Flutter亦可支持Web开发(Flutter for web)和PC开发

    • 高性能

    Flutter高性能主要靠两点来保证,首先,Flutter APP采用Dart语言开发。Dart在 JIT(即时编译)模式下,速度与 JavaScript基本持平。但是 Dart支持 AOT,当以 AOT模式运行时,JavaScript便远远追不上了。速度的提升对高帧率下的视图数据计算很有帮助。其次,Flutter使用自己的渲染引擎来绘制UI,布局数据等由Dart语言直接控制,所以在布局过程中不需要像RN那样要在JavaScript和Native之间通信,这在一些滑动和拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以JavaScript需要和Native之间不停的同步布局信息,这和在浏览器中要JavaScript频繁操作DOM所带来的问题是相同的,都会带来比较可观的性能开销。

    • 采用Dart语言开发
    JIT和AOT

    目前,程序主要有两种运行方式:静态编译与动态解释

    • 静态编译/AOT /提前编译:程序在执行前全部被翻译为机器码
      • AOT程序的典型代表是用C/C++开发的应用,它们必须在执行前编译成机器码
    • 即时编译/JIT:一句一句边翻译边运行
      • JIT的代表则非常多,如JavaScript、python等;
      • 所有脚本语言都支持JIT模式

    需要注意的是JIT和AOT指的是程序运行方式,和编程语言并非强关联的,有些语言既可以以JIT方式运行也可以以AOT方式运行,如Java、Python,它们可以在第一次执行时编译成中间字节码、然后在之后执行时可以直接执行字节码,也许有人会说,中间字节码并非机器码,在程序执行时仍然需要动态将字节码转为机器码,是的,这没有错,不过通常我们区分是否为AOT的标准就是看代码在执行之前是否需要编译,只要需要编译,无论其编译产物是字节码还是机器码,都属于AOT。

    dart开发优势

    1. 开发效率高
      Dart运行时和编译器支持Flutter的两个关键特性的组合:
      基于JIT的快速开发周期:Flutter在开发阶段采用,采用JIT模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;
      基于AOT的发布包: Flutter在发布时可以通过AOT生成高效的ARM代码以保证应用性能。而JavaScript则不具有这个能力。
    2. 高性能
      Flutter旨在提供流畅、高保真的的UI体验。为了实现这一点,Flutter中需要能够在每个动画帧中运行大量的代码。这意味着需要一种既能提供高性能的语言,而不会出现会丢帧的周期性暂停,而Dart支持AOT,在这一点上可以做的比JavaScript更好。
    3. 快速内存分配
      Flutter框架使用函数式流,这使得它在很大程度上依赖于底层的内存分配器。因此,拥有一个能够有效地处理琐碎任务的内存分配器将显得十分重要,在缺乏此功能的语言中,Flutter将无法有效地工作。当然Chrome V8的JavaScript引擎在内存分配上也已经做的很好,事实上Dart开发团队的很多成员都是来自Chrome团队的,所以在内存分配上Dart并不能作为超越JavaScript的优势,而对于Flutter来说,它需要这样的特性,而Dart也正好满足而已。
    4. 类型安全
      由于Dart是类型安全的语言,支持静态类型检测,所以可以在编译前发现一些类型的错误,并排除潜在问题,这一点对于前端开发者来说可能会更具有吸引力。与之不同的,JavaScript是一个弱类型语言,也因此前端社区出现了很多给JavaScript代码添加静态类型检测的扩展语言和工具,如:微软的TypeScript以及Facebook的Flow。相比之下,Dart本身就支持静态类型,这是它的一个重要优势。
    5. Dart团队就在你身边
      看似不起眼,实则举足轻重。由于有Dart团队的积极投入,Flutter团队可以获得更多、更方便的支持,正如Flutter官网所述“我们正与Dart社区进行密切合作,以改进Dart在Flutter中的使用。例如,当我们最初采用Dart时,该语言并没有提供生成原生二进制文件的工具链(这对于实现可预测的高性能具有很大的帮助),但是现在它实现了,因为Dart团队专门为Flutter构建了它。同样,Dart VM之前已经针对吞吐量进行了优化,但团队现在正在优化VM的延迟时间,这对于Flutter的工作负载更为重要。

    Flutter框架结构

    从上向下,越来越底层
    在这里插入图片描述

    • Framework:这是一个纯 Dart实现的 SDK,它实现了一套基础库,自底向上,我们来简单介绍一下:
      • 底下两层(Foundation和Animation、Painting、Gestures)在Google的一些视频中被合并为一个dart UI层,对应的是Flutter中的dart:ui包,它是Flutter引擎暴露的底层UI库,提供动画、手势及绘制能力。
      • Rendering层,这一层是一个抽象的布局层,它依赖于dart UI层,Rendering层会构建一个UI树,当UI树有变化时,会计算出有变化的部分,然后更新UI树,最终将UI树绘制到屏幕上,这个过程类似于React中的虚拟DOM。Rendering层可以说是Flutter UI框架最核心的部分,它除了确定每个UI元素的位置、大小之外还要进行坐标变换、绘制(调用底层dart:ui)。
      • Widgets层是Flutter提供的的一套基础组件库
      • Material 和Cupertino两种视觉风格的组件库。而我们Flutter开发的大多数场景,只是和这两层打交道
    • Engine:这是一个纯 C++实现的 SDK,其中包括了 Skia引擎、Dart运行时、文字排版引擎等。在代码调用 dart:ui库时,调用最终会走到Engine层,然后实现真正的绘制逻辑。

    flutter项目结构

    • android:安卓资源文件
    • build:运行的编译目录
    • ios
    • lib:写代码的目录
    • test:测试文件
    • .metadata
    • .packages
    • fluttertestone.iml
    • pubspec.lock
    • pubspec.yaml:配置文件
    • README.md

    flutter的基础结构介绍

    用Android Studio和VS Code创建的Flutter应用模板默认是一个简单的计数器示例。

    import 'package:flutter/material.dart';
     
    void main() => runApp(new MyApp());
     
    class MyApp extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
     
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
     
      
      _MyHomePageState createState() => new _MyHomePageState();
    }
     
    class _MyHomePageState extends State<MyHomePage> {
      int _counter = 0;
     
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
     
      
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text(widget.title),
          ),
          body: new Center(
            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.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: new Icon(Icons.add),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    在这里插入图片描述

    在lib中的main.dart是主类

    material组件库
    • 导入包。
    import 'package:flutter/material.dart';//谷歌推出的样式库,扁平化,比较大气
    
    • 1

    此行代码作用是导入了Material UI组件库。Material是一种标准的移动端和web端的视觉设计语言, Flutter默认提供了一套丰富的Material风格的UI组件。

    main
    • 应用入口。
    void main() => runApp(MyApp());//定义主类调用MyApp
    
    • 1
    • 与C/C++、Java类似,Flutter 应用中main函数为应用程序的入口。main函数中调用了runApp 方法,它的功能是启动Flutter应用。runApp它接受一个Widget参数,在本示例中它是一个MyApp对象,MyApp()是Flutter应用的根组件。
    • main函数使用了(=>)符号,这是Dart中单行函数或方法的简写。
    import 'package:flutter/material.dart';//全局引入
     
    void main() => runApp(MyApp());//定义主类调用MyApp
    
    • 1
    • 2
    • 3

    在lib中的main.dart是主类,例如

    import 'package:flutter/material.dart';//主类引用
     
    void main(){
      //new 可以省略
      runApp(new Center(//中间
        child:new Text(//输出文本
          '你好Flutter',
          textDirection: TextDirection.ltr,
        )
      ));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在屏幕中心显示了

    组件模板
    class MyApp extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return new MaterialApp(
          //应用名称 
          title: 'Flutter Demo',
          theme: new ThemeData(
            //蓝色主题 
            primarySwatch: Colors.blue,
          ),
          //应用首页路由 
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • MyApp类代表Flutter应用,它继承了 StatelessWidget类,这也就意味着应用本身也是一个widget。
    • 在Flutter中,大多数东西都是widget(后同“组件”或“部件”),包括对齐(alignment)、填充(padding)和布局(layout)等,它们都是以widget的形式提供。
    • Flutter在构建页面时,会调用组件的build方法,widget的主要工作是提供一个build()方法来描述如何构建UI界面(通常是通过组合、拼装其它基础widget)。
    • MaterialApp 是Material库中提供的Flutter APP框架,通过它可以设置应用的名称、主题、语言、首页及路由列表等。MaterialApp也是一个widget。
    • home 为Flutter应用的首页,它也是一个widget。
    首页
       class MyHomePage extends StatefulWidget {
         MyHomePage({Key key, this.title}) : super(key: key);
         final String title;
         
         _MyHomePageState createState() => new _MyHomePageState();
       }
     
       class _MyHomePageState extends State<MyHomePage> {
        ...
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    MyHomePage 是Flutter应用的首页,它继承自StatefulWidget类,表示它是一个有状态的组件(Stateful widget)。

    组件模板

    在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget/StatefulWidget

    • StatelessWidget 是无状态组件,状态不可变的 widget
    • StatefulWidget 是有状态组件,持有的状态可能在 widget 生命周期改变
      • Stateful widget至少由两个类组成
        • 一个StatefulWidget类。
        • 一个 State类; StatefulWidget类本身是不变的,但是State类中持有的状态在widget生命周期中可能会发生变化。

    StatelessWidget无状态模板

    class name extends StatelessWidget {
      const name({Key key}) : super(key: key);
     
      
      Widget build(BuildContext context) {
        return Container(
          child: child,
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    StatefulWidget有状态模板

    class name extends StatefulWidget {
      name({Key key}) : super(key: key);
     
      
      _nameState createState() => _nameState();
    }
     
    class _nameState extends State<name> {
      
      Widget build(BuildContext context) {
        return Container(
           child: child,//需要定义的组件内容
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    案例

    无状态案例
    import 'package:flutter/material.dart';//谷歌推出的样式库,扁平化,比较大气
     
    void main() => runApp(MyApp());//定义主类调用MyApp
     
    class MyApp extends StatelessWidget {//继承静态组件
      // 重写构建方法
      
      Widget build(BuildContext context) {
        //返回组件
        return MaterialApp(
          //标题
          title: 'Flutter Demo',
          // theme: ThemeData(
          //   primarySwatch: Colors.blue,
          // ),
          //脚手架
          // home: MyHomePage(title: 'Flutter Demo Home Page '),
          home: Scaffold(
            appBar: AppBar(
              title: Text('hello'),//页面标题
            ),
            body: Center(
              child:Text('hello2'),//主体内容
            ),
          ),
     
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    点击按钮,数字加1
    import 'package:flutter/material.dart';
     
    void main() => runApp(MyApp());//main调用无状态组件
     
    class MyApp extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
          appBar: AppBar(title: Text('Flutter Demo')),
          body: HomePage(),//调用有状态组件
        ));
      }
    }
     
    //自定义有状态组件
    class HomePage extends StatefulWidget {
      HomePage({Key key}) : super(key: key);
      _HomePageState createState() => _HomePageState();
    }
     
    class _HomePageState extends State<HomePage> {
      int countNum = 0;
      
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            SizedBox(height: 200),
            Chip(
              label: Text('${this.countNum}'),
            ),
            SizedBox(height: 20),
            RaisedButton(
              child: Text('按钮'),
              onPressed: () {//点击按钮
                setState(() {//使用setState,更新页面中显示的值,类似vue的绑定
                  //只有有状态组件里面才有
                  this.countNum++;
                });
              },
            )
          ],
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    点击按钮,list中添加内容
    class HomePage extends StatefulWidget {
      HomePage({Key key}) : super(key: key);
     
      _HomePageState createState() => _HomePageState();
    }
     
    class _HomePageState extends State<HomePage> {
      List list = new List();
      
      Widget build(BuildContext context) {
        return ListView(
          children: <Widget>[
            Column(
                children: this.list.map((value) {
              return ListTile(
                title: Text(value),
              );
            }).toList()),
            SizedBox(height: 20),
            RaisedButton(
              child: Text("按钮"),
              onPressed: () {
                setState(() {//设置内容需要在setState方法中
                  this.list.add('新增数据1');
                  this.list.add('新增数据2');
                });
              },
            )
          ],
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    Unity捏脸工具
    Docker部署homeassitant
    【Git学习三】git中的分支管理:git branch,git checkout,解决git中的分支冲突的方法
    关于 Redis 必问面试题,你知道哪些?
    Android串口编程入门
    pyqt5 学习笔记四 (布局:QBoxLayout)
    入职芯片开发部后,每天摸鱼之外的时间我们要做些什么呢
    10个Python脚本来自动化你的日常任务
    c++编程实例
    【Java面试】概念性的问题怎么答,看完高手的回答一口气答出完整思路,Nosql的理解
  • 原文地址:https://blog.csdn.net/qq_36254947/article/details/133817915