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)
  • 生态环境
  • 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应用模板默认是一个简单的计数器示例。

dart 复制代码
import 'package:flutter/material.dart';
 
void main() => runApp(new MyApp());
 
class MyApp extends StatelessWidget {
  @override
  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;
 
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}
 
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
 
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
 
  @override
  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.
    );
  }
}

在lib中的main.dart是主类

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

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

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

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

dart 复制代码
import 'package:flutter/material.dart';//主类引用
 
void main(){
  //new 可以省略
  runApp(new Center(//中间
    child:new Text(//输出文本
      '你好Flutter',
      textDirection: TextDirection.ltr,
    )
  ));
}

在屏幕中心显示了

组件模板
dart 复制代码
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      //应用名称 
      title: 'Flutter Demo',
      theme: new ThemeData(
        //蓝色主题 
        primarySwatch: Colors.blue,
      ),
      //应用首页路由 
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
  • 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。
首页
dart 复制代码
   class MyHomePage extends StatefulWidget {
     MyHomePage({Key key, this.title}) : super(key: key);
     final String title;
     @override
     _MyHomePageState createState() => new _MyHomePageState();
   }
 
   class _MyHomePageState extends State<MyHomePage> {
    ...
   }

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

组件模板

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

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

StatelessWidget无状态模板

dart 复制代码
class name extends StatelessWidget {
  const name({Key key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return Container(
      child: child,
    );
  }
}

StatefulWidget有状态模板

dart 复制代码
class name extends StatefulWidget {
  name({Key key}) : super(key: key);
 
  @override
  _nameState createState() => _nameState();
}
 
class _nameState extends State<name> {
  @override
  Widget build(BuildContext context) {
    return Container(
       child: child,//需要定义的组件内容
    );
  }
}

案例

无状态案例
dart 复制代码
import 'package:flutter/material.dart';//谷歌推出的样式库,扁平化,比较大气
 
void main() => runApp(MyApp());//定义主类调用MyApp
 
class MyApp extends StatelessWidget {//继承静态组件
  // 重写构建方法
  @override
  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
dart 复制代码
import 'package:flutter/material.dart';
 
void main() => runApp(MyApp());//main调用无状态组件
 
class MyApp extends StatelessWidget {
  @override
  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;
  @override
  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++;
            });
          },
        )
      ],
    );
  }
}
点击按钮,list中添加内容
dart 复制代码
class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);
 
  _HomePageState createState() => _HomePageState();
}
 
class _HomePageState extends State<HomePage> {
  List list = new List();
  @override
  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');
            });
          },
        )
      ],
    );
  }
}
相关推荐
西岸行者13 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意13 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码13 天前
嵌入式学习路线
学习
毛小茛13 天前
计算机系统概论——校验码
学习
babe小鑫13 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms13 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下13 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。13 天前
2026.2.25监控学习
学习
im_AMBER13 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J13 天前
从“Hello World“ 开始 C++
c语言·c++·学习