001flutter基础学习

news2024/11/25 18:30:08

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.
    );
  }
}

在这里插入图片描述

在lib中的main.dart是主类

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

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

main
  • 应用入口。
void main() => runApp(MyApp());//定义主类调用MyApp
  • 与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

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

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

在屏幕中心显示了

组件模板
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'),
    );
  }
}
  • 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> {
    ...
   }

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,
    );
  }
}

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,//需要定义的组件内容
    );
  }
}

案例

无状态案例
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
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++;
            });
          },
        )
      ],
    );
  }
}
点击按钮,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');
            });
          },
        )
      ],
    );
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1089742.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Rt-Thread 移植4--对象容器实现(KF32)

1.对象 1,1 什么是对象 所有的数据结构都是对象 1.2代码实现 1.2.1 对象类型枚举定义 rtdef.h 添加rt_object_class_type enum rt_object_class_type{RT_Object_Class_NULL0,RT_Object_Class_Thread ,RT_Object_Class_Semaphore,RT_Object_Class_Mutex,RT_Object_Class_E…

【java学习】JavaBean(28)

文章目录 1. 概念 1. 概念 JavaBean 是一种 Java 语言写成的可重用组件。 所谓 javaBean &#xff0c;是指符合如下标准的 Java 类&#xff1a; (1) 类是公共的 (2) 有一个无参的公共的构造器 (3) 有属性&#xff0c;属性一般是私有的&#xff0c;且有对应的 get 、set 方法 …

cad问题:无法识别的版本,不能读取

cad安装目录或文件名、新建时的文件模板&#xff0c;含有“无”这个字就会出现此问题&#xff0c;只要把 无这个字改成没&#xff0c;即可解决

Kafka进阶

Kafka进阶 Kafka事务 kafka的事务机制是指kafka支持跨多个主题和分区的原子性写入&#xff0c;即在一个事务中发送的所有消息要么全部成功&#xff0c;要么全部失败。 kafka的事务机制涉及到以下几个方面&#xff1a; 事务生产者&#xff08;transactional producer&#x…

【牛客面试必刷TOP101】Day12.BM72 连续子数组的最大和和BM80 买卖股票的最好时机(一)

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…

StatefulSet 简单实践 Kubernetes

概述 在Kubernetes集群中部署MySQL和Mongodb的StatefulSet服务。 MySQL有官方文档的指引 其他网站博客的指引实现 Mongodb修改operator的Deployment进行简单的实现 MySQL-StatefulSet 参考官方文档&#xff1a;运行一个有状态的应用程序 | Kubernetes 深入剖析Kubernete…

matlab第三方硬件支持包下载和安装

1、在使用matlab内部的附加功能安装时&#xff0c;由于matlab会验证是否正版无法打开 2、在matlab官网直接找到对应的硬件支持包下载&#xff0c;但是是下图的安装程序 可以直接在matlab中跳转到该程序所在的文件夹双击安装&#xff0c;但是安装到最后出错了 3.根据出错时mala…

创邻科技Galaxybase—激活数据要素的核心引擎

10月11日下午&#xff0c;创邻科技创始人张晨博士受杭州电子科技大学邀请&#xff0c;前往杭电校园开展交流分享。交流会中&#xff0c;张晨博士为现场的师生带来一场题为《图数据库——激活数据要素的新基建》的精彩分享&#xff0c;探讨数字经济时代底层技术的创新价值与图技…

CRM系统管理多渠道客户的方法

很多企业同时拥有多个销售渠道&#xff0c;由于客户来自不同的销售渠道&#xff0c;数据非常分散&#xff0c;管理起来费时费力。或许您可以使用CRM客户管理系统来管理不同渠道的客户&#xff0c;下面说说企业常见的销售渠道有哪些&#xff1f;CRM系统如何管理多渠道客户&#…

一招搞定,终止端口号进程

场景&#xff1a;聪明的小明写了个到点执行关机的脚本&#xff0c;再次启动项目时发现端口号占用&#xff0c;操作步骤来了。 步骤1&#xff1a; winr&#xff0c;cmd走起 netstat -ano | findstr "端口号" 步骤2&#xff1a; 查询该进程 tasklist | findstr "P…

苹果macOS Sonoma 14正式版 “黑苹果”且用且珍惜

9月下旬&#xff0c;苹果正式发布了全新的桌面操作系统macOS Sonoma 14&#xff0c;对于一众的“黑苹果”用户来说&#xff0c;这是个让人既兴奋又害怕的消息&#xff0c;兴奋的是又有新系统可以升级了&#xff0c;害怕的是“黑苹果”距离寿终正寝的时间也越来越近了。 所谓的“…

软件测试面试基础篇(含答案)

1、你的测试职业发展是什么&#xff1f; 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前 3 年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&a…

【QT】Ubuntu 交叉编译安装 QT 5.12.7 源码

目录 1、下载 QT 源码包 2、搭建安装环境(下载依赖库) 3、创建QT源码编译脚本 4、运行编译脚本 1、下载 QT 源码包 QT5.12.7源码下载地址: download | QT 5.12.7 选择任意一种下载即可&#xff0c;适用于 Windows 和 Linux 环境 这里选择的是.tar.xz 类型&#xff0c;上…

CustomNavBar 自定义导航栏视图

1. 创建偏好设置键 CustomNavBarTitlePreferenceKey.swift import Foundation import SwiftUI//State private var showBackButton: Bool true //State private var title: String "Title" //"" //State private var subtitle: String? "SubTitl…

树莓派部署.net core网站程序

1、发布你的项目 使用mobaxterm上传程序 回到mobaxterm,f进入目录输入&#xff1a; cd webpublish 运行程序&#xff1a;dotnet WebApplication1.dll 访问地址为&#xff1a;http://localhost:5000,尝访问如下&#xff1a; 已经出现 返回的json&#xff0c;证明是可以访问的…

阿里云服务器通用型规格族20个实例规格性能特点和适用场景汇总

阿里云服务器ECS通用型规格族属于独享型云服务器&#xff0c;实例采用固定CPU调度模式&#xff0c;实例的每个CPU绑定到一个物理CPU超线程&#xff0c;实例间无CPU资源争抢&#xff0c;实例计算性能稳定且有严格的SLA保证&#xff0c;在性能上会更加稳定&#xff0c;高负载情况…

AI:38-基于深度学习的抽烟行为检测

随着人工智能的迅猛发展,它在各个领域展现出了广泛的应用潜力。其中,基于深度学习的抽烟行为检测技术引起了人们的极大兴趣。这项技术利用计算机视觉和深度学习算法,能够自动检测和监测人们的抽烟行为,为烟草控制和公共卫生提供了新的手段。本文将深入探讨基于深度学习的抽…

01-网络篇-网络分层和常见网络协议

常使用的网络有广域网&#xff08;WAN&#xff09;、城域网、局域网&#xff08;LAN&#xff09;&#xff0c;一般我们遇到的场景是广域网和局域网&#xff0c;广域网就是常说的外网&#xff0c;而局域网一般用于学校、公司等场合。在家庭路由器中对应WAN口和LAN口。网络是极为…

Windows 定时备份 pg 数据库,定时删除

目录 1. 写个备份脚本2. Windows 添加定时任务3. 使用备份的 SQL 还原数据 1. 写个备份脚本 备份数据库脚本&#xff1a; pgBacks.bat ECHO OFF :: 用于启用扩展功能。在使用enableextensions选项后&#xff0c;批处理脚本可以使用扩展命令和特性 setlocal enableextensions…

Sprint framework Day08:Spring的@Autowired注解

前言 当使用注解和 XML 配置结合时&#xff0c;可以使用注解 Autowired、Qualifier 和 Primary 来实现自动装配并进行依赖注入。 一、了解 Autowired、Qualifier 和 Primary 注解 Autowired 注解&#xff1a;用于自动装配依赖。在需要进行依赖注入的地方&#xff0c;添加 Auto…