美文网首页
Flutter学习笔记 (一)

Flutter学习笔记 (一)

作者: 送我迷迭香 | 来源:发表于2021-08-24 15:53 被阅读0次

    (一)初识Flutter

    1.Flutter是什么

    Flutter is Google's UI toolkit for building beautiful, natively compiled applications for mobile, web, desktop, and embedded devices from a single codebase.

    官方是这么描述的,简单来说,Flutter是一个UI SDK (Software Development Kit),可以进行移动端(iOS、Android),Web端,桌面的跨平台解决方案

    2.Flutter的特点

    • 美观
      使用Flutter内置的Material Design 和Cupertino widget 、丰富的motion API ,平滑自然的滑动效果和平台感知,为用户带来全新的体验

    • 快速
      Flutter引擎使用C++编写,包括高效的Skia 2D渲染引擎,Dart 运行时和文本渲染库

    • 高效
      Hot Reload

    • 开放
      开源

    3.Flutter 绘制原理

    image.png
    • GPU将信号同步到UI线程
    • UI线程用Dart构建图层树
    • 图层树在GPU线程进行合成
    • 合成后将视图数据提供给Skia引擎
    • Skia引擎通过OpenGL 或者 Vulkan 将内容提供给GPU

    4.渲染引擎 Skia

    Skia(全称Skia Graphics Library (SGL))就是Flutter向GPU提供数据的途径,是一个C++编写的开源图形库,能在低端设备如手机上呈现高质量的2D图形,最初由Skia公司开发,后被Google收购

    • 应用于Android、Google Chrome、Chrome OS等等当中
    • 目前, Skia已经是Android官方的图像渲染弓|擎了,因此Flutter Android
      SDK无需内嵌Skia弓|擎就可以获得Skia支持
    • 而对于iOS平台来说,由于Skia是跨平台的,因此它作为Flutter ioS渲染引
      擎被嵌入到Flutter的iOS SDK中,替代了iOS闭源的Core Graphics/Core
      Animation/Core Text ,这也正是Flutter iOS SDK打包的App包体积比
      Android要大一些的原因
    • 底层渲染能力统一了,上层开发接口和功能体验也就随即统一了,开发者再也不用操心平台相关的渲染特性了。也就是说, Skia保证了同一套代码调用在
      Android和iOS平台上的渲染效果是完全一致的。
    image.png

    (二)环境搭建

    1.安装Flutter SDK (MacOS为例)

    去官网下载最新的安装包 Flutter SDK releases - Flutter

    1.解压到想要安装的路径

    cd ~/development
    unzip ~/Downloads/flutter_macos_v0.5.1-beta.zip
    

    3.添加flutter相关工具到path中:

    export PATH=`pwd`/flutter/bin:$PATH
    

    4.运行 flutter doctor

    运行以下命令查看是否需要安装其它依赖项来完成安装:

    flutter doctor
    

    5.配置环境

    export PUB_HOSTED_URL=https://pub.flutter-io.cn //国内用户需要设置
    export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn //国内用户需要设置
    export PATH=PATH_TO_FLUTTER_GIT_DIRECTORY/flutter/bin:$PATH
    

    6.开发工具选择

    官方推荐 Android Studio 或者 VSCode

    (三)Flutter初体验

    1.创建Flutter项目

    可以通过两种方式创建,1 终端 2.编辑器 ,以终端为例

    flutter create myapp
    $ cd myapp
    

    上述命令创建一个Flutte让项目,项目名为myapp,其中包含一个使用Material 组件的简单演示应用程序。

    在项目目录中,您的应用程序的代码位于 lib/main.dart.

    2.运行应用程序

    • 检查设备是否在运行。如果没有显示, 请参照 设置.
    $ flutter devices
    
    • 运行 flutter run 命令来运行应用程序:
    $ flutter run
    

    3.体验热重载

    Flutter 可以通过 热重载(hot reload) 实现快速的开发周期,热重载就是无需重启应用程序就能实时加载修改后的代码,并且不会丢失状态(译者语:如果是一个web开发者,那么可以认为这和webpack的热重载是一样的)。简单的对代码进行更改,然后告诉IDE或命令行工具你需要重新加载(点击reload按钮),你就会在你的设备或模拟器上看到更改。

    打开文件lib/main.dart
    将字符串
    'You have pushed the button this many times:' 更改为
    'You have clicked the button this many times:'
    不要按“停止”按钮; 让您的应用继续运行.
    要查看您的更改,请调用 Save (cmd-s / ctrl-s), 或者点击 热重载按钮 (带有闪电图标的按钮).

    (四) 认识 Dart

    1.安装Dart

    为什么还需要安装Dart呢?
    事实上在安装Flutter SDK的时候,它已经内置了Dart了,我们完全可以直接使用Flutter去进行Dart的编写并且运行。
    但是,如果你想单独学习Dart,并且运行自己的Dart代码,最好去安装一个Dart SDK。

    官方网站:https://dart.dev/get-dart,下载完成后,根据路径配置环境变量即可。
    以VSCode为例,去扩展添加Dart插件

    image.png

    2.hello Dart

    在VSCode中新建一个helloWorld.dart文件

    main(List<String> args) {
      print('Hello World');
    }
    

    执行快捷键 control + option + N

    3.程序分析

    一、Dart语言的入口也是main函数,并且必须显示的进行定义;

    二、Dart的入口函数main是没有返回值的;

    三、传递给main的命令行参数,是通过List<String>完成的。

    从字面值就可以理解List是Dart中的集合类型。

    其中的每一个String都表示传递给main的一个参数;

    四、定义字符串的时候,可以使用单引号或双引号;

    五、每行语句必须使用分号结尾,很多语言并不需要分号,比如Swift、JavaScript;

    (五)Dart 语法

    1. 明确声明(Explicit)

    明确声明变量的方式, 格式如下:

    变量类型 变量名称 = 赋值;
    
    String name = 'abc';
    int age = 18;
    double height = 1.88;
    print('${name}, ${age}, ${height}'); // 拼接
    

    注意事项: 定义的变量可以修改值, 但是不能赋值其他类型

    2. 类型推导(Type Inference)

    类型推导声明变量的方式, 格式如下:

    var/dynamic/const/final 变量名称 = 赋值
    
    2.1. var的使用

    runtimeType用于获取变量当前的类型

    var name = 'abc';
    name = 'kobe';
    print(name.runtimeType); // String
    
    //var age = 18;
    //age = 'why'; // 不可以将String赋值给一个int类型
    
    2.2. dynamic的使用
    dynamic name = 'abc';
    print(name.runtimeType); // String
    name = 18;
    print(name.runtimeType); // int
    
    2.3. final&const的使用

    final和const都是用于定义常量的, 也就是定义之后值都不可以修改

    final name = 'coderwhy';
    name = 'kobe'; // 错误
    
    const age = 18;
    age = 20; // 错误
    

    final和const有什么区别呢?

    const在赋值时, 赋值的内容必须是在编译期间就确定下来的

    final在赋值时, 可以动态获取, 比如赋值一个函数

    String getName() {
      return 'abc';
    }
    
    main(List<String> args) {
      const name = getName(); // 错误的做法, 因为要执行函数才能获取到值
      final name = getName(); // 正确的做法
    }
    

    3.数据类型

    3.1 数字类型

    对于数值来说,我们也不用关心它是否有符号,以及数据的宽度和精度等问题。只要记着整数用int,浮点数用double就行了。Dart中的intdouble可表示的范围并不是固定的,它取决于运行Dart的平台。

    
    // 1.整数类型int
    int age = 18;
    int hexAge = 0x12;
    print(age);
    print(hexAge);
    
    // 2.浮点类型double
    double height = 1.88;
    print(height);
    

    字符串和数字间转化

    // 1.字符串转数字
    var one = int.parse('111');
    var two = double.parse('12.22');
    print('${one} ${one.runtimeType}'); // 111 int
    print('${two} ${two.runtimeType}'); // 12.22 double
    
    // 2.数字转字符串
    var num1 = 123;
    var num2 = 123.456;
    var num1Str = num1.toString();
    var num2Str = num2.toString();
    var num2StrD = num2.toStringAsFixed(2); // 保留两位小数
    print('${num1Str} ${num1Str.runtimeType}'); // 123 String
    print('${num2Str} ${num2Str.runtimeType}'); // 123.456 String
    print('${num2StrD} ${num2StrD.runtimeType}'); // 123.46 String
    
    3.2 bool类型

    Dart提供了一个bool的类型, 取值为true和false

    var isFlag = true;
    print('$isFlag ${isFlag.runtimeType}');
    

    Dart中不能判断非0即真, 或者非空即真
    不能使用if(非booleanvalue)或assert(非booleanvalue)之类的代码。

     var message = 'Hello Dart';
      // 错误的写法
      if (message) {
        print(message)
      }
    
    3.3 字符串类型

    Dart字符串是UTF-16编码单元的序列。可以使用单引号或双引号创建一个字符串:

    // 1.定义字符串的方式
    var s1 = 'Hello World';
    var s2 = "Hello Dart";
    var s3 = 'Hello\'Fullter';
    var s4 = "Hello'Fullter"
    

    可以使用三个单引号或者双引号表示多行字符串:

    // 2.表示多行字符串的方式
    var message1 = '''
    哈哈哈
    呵呵呵
    嘿嘿嘿''';
    

    字符串和其他变量或表达式拼接: 使用${expression}, 如果表达式是一个标识符, 那么{}可以省略

    // 3.拼接其他变量
    var name = 'ABC';
    var age = 18;
    var height = 1.88;
    print('my name is ${name}, age is $age, height is $height');
    
    3.4 集合类型
    3.4.1 集合类型的定义

    Dart内置了最常用的三种:List / Set / Map

    
    // List定义
    // 1.使用类型推导定义
    var letters = ['a', 'b', 'c', 'd'];
    print('$letters ${letters.runtimeType}');
    
    // 2.明确指定类型
    List<int> numbers = [1, 2, 3, 4];
    print('$numbers ${numbers.runtimeType}');
    
    
    // Set的定义
    // 1.使用类型推导定义
    var lettersSet = {'a', 'b', 'c', 'd'};
    print('$lettersSet ${lettersSet.runtimeType}');
    
    // 2.明确指定类型
    Set<int> numbersSet = {1, 2, 3, 4};
    print('$numbersSet ${numbersSet.runtimeType}');
    

    Set和List最大的两个不同就是:Set是无序的,并且元素是不重复的。

    // Map的定义
    // 1.使用类型推导定义
    var infoMap1 = {'name': 'why', 'age': 18};
    print('$infoMap1 ${infoMap1.runtimeType}');
    
    // 2.明确指定类型
    Map<String, Object> infoMap2 = {'height': 1.88, 'address': '北京市'};
    print('$infoMap2 ${infoMap2.runtimeType}');
    
    3.4.2 集合的常见操作
    // 获取集合的长度
    print(letters.length);
    print(lettersSet.length);
    print(infoMap1.length);
    
    // 添加/删除/包含元素
    numbers.add(5);
    numbersSet.add(5);
    print('$numbers $numbersSet');
    
    numbers.remove(1);
    numbersSet.remove(1);
    print('$numbers $numbersSet');
    
    print(numbers.contains(2));
    print(numbersSet.contains(2));
    
    // List根据index删除元素
    numbers.removeAt(3);
    print('$numbers');
    
    // Map的操作
    // 1.根据key获取value
    print(infoMap1['name']); 
    
    // 2.获取所有的entries
    print('${infoMap1.entries} ${infoMap1.entries.runtimeType}'); // (MapEntry(name: why), MapEntry(age: 18)) MappedIterable<String, MapEntry<String, Object>>
    
    // 3.获取所有的keys
    print('${infoMap1.keys} ${infoMap1.keys.runtimeType}'); // (name, age) _CompactIterable<String>
    
    // 4.获取所有的values
    print('${infoMap1.values} ${infoMap1.values.runtimeType}'); // (why, 18) _CompactIterable<Object>
    
    // 5.判断是否包含某个key或者value
    print('${infoMap1.containsKey('age')} ${infoMap1.containsValue(18)}'); // true true
    
    // 6.根据key删除元素
    infoMap1.remove('age');
    print('${infoMap1}'); // {name: why}
    

    相关文章

      网友评论

          本文标题:Flutter学习笔记 (一)

          本文链接:https://www.haomeiwen.com/subject/wqydiltx.html