Flutter的几点小认识

目录

flutter knowledge image one

1.Flutter是什么?
  • Flutter是Google papa推出的一款全新的,响应式·跨平台·高性能的移动开发框架。
2. Flutter与其他框架对比
  • 在移动开发的中的跨平台中有以下几种方案:
    • 基于WebView 和JavaScript(Cordova,AppCan)
    • 基于HTML和JavaScript渲染映射成原生控件(ReatNative、Weex)
    • 基于微信生态的小程序
    • 基于原生编码无桥接(Flutter)
方案优点缺点
基于WebView和JavaScript的方案(Cordova)1. 可以继承Web开发的所有成果
(丰富的控件库,满足各种需求的页面框架,完全动态化,自动化测试工具等)
2.学习成本低(不需要太多的成本和迁移成本就可以开发一个app)
1.WebView渲染效率和JavaScript的执行性能太差
2.由于Android各个系统版本和厂商的定制,很难保证在所有设备有一致的效果
基于HTML(vue)和JavaScript渲染映射成原生控件(ReatNative,Weex)1.将渲染工作交给原生,性能体验好
2.Facebook出品推出时间较长,社区资源丰富
随系统版本变化和API的变化,需要处理不同平台的差异,有的特性不能满足所有平台(第三方库良莠不齐,维护困难)
基于微信生态的小程序1.迭代速度快,学习成本低
2.可以实现动态无缝更新,可以利用微信强大的用户基数
依赖于微信产品生态,定制程度大打折扣
基于原生编码无桥接的Flutter1.热重载
2.渲染引擎依赖跨平台的Skia图形库(一个开源的2D图形库在一系列硬件和软件平台提供通用的API),可以最大程度保证不同平台和设备的体验一致性
3.使用支持AOT的Dart语言,执行效率比JavaScript好很多
4.美观可定制的组件
1.dart 语言的生态小,精通成本比较高
2.嵌入外部 platform view 成本高这块(基于官方代码)目前在 iOS 端有支持,android 上还没有,但相关开发者博客上有提到实现了webview,mapview 等 platform view 的嵌入。从 iOS 端的实现来看,每嵌入一层 platform view 会额外多一层 surface,内存代价比较高
3.flutter 目前提供的开箱即用的功能只有 UI framework + dart 语言的能力,平台能力需要通过 platform channel 来扩展。(目前丰富的程度有限,未来可期
3.Flutter的Dart架构和Dart语言
  • Flutter的框架部分全部完全使用Dart语言实现,有着清晰的分层架构。分层架构使得我们可以在调用Flutter提供的便捷开发功能之外,还可以修改每一层额实现Framework的底层是flutter引擎,引擎主要负责图形绘制(skia),文字排版(libtxt)和提供Dart运行时,引擎全部使用C++实现,Framework层使我们可以用Dart语言引擎的强大能力.
    flutter架构
    源码架构

    Dart部分的最低层为Foundation其中大都是非常基础的,提供给其他所有层的工具类和方法。
    绘制库(Painting 封装了Flutter Engine 提供的绘制接口,主要是为了在绘制控制等固定样式时提供更直观,更方便的接口,比如绘制缩放后的位图,绘制文本,插值生成阴影以及在盒子周围绘制边框等。
    Animation动画类提供了类似Android系统的ValueAnimator的功能,并且提供了丰富的内置插值器。
    Gesture手势类提供了手势识别相关功能,包括触摸事件类定义和多种内置的手势识别器。GestureBinding类是Flutter中处理手势的抽象服务类,继承自BindingBase类。

    Binding系列的类在Flutter中充当类似于Android中的SystemService系列(ActivityManager,PackageManager)功能,每个Binding类提供一个服务的单例对象,App最顶层的Binding会包含所有相关的Binding抽象类。如果使用Flutter提供的控件开发,则需要使用WidgetsFlutterBinding,如果不使用Flutter提供的控件而直接调用Render层,则需要使用RenderingFlutterBinding。

    • 渲染库(Rendering)

      • Flutter的控件在实际显示时会转换成对应的渲染对象(RenderObject)树来实现布局和绘制操作。一般情况下,我们只会在调试布局,或者需要使用自定义控件来实现某些特殊效果的时候,才需要考虑渲染对象的细节。渲染库主要提供的功能类有:
        (对于mixin的Dart语言机制可以参考Flutter基础:理解Dart的Mixin继承机制

        /// The glue between the render tree and the Flutter engine.
        //RendererBinding是渲染树和Flutter引擎的胶水:负责管理帧重绘,窗口尺寸和渲染相关变化的监听
        mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureBinding, SemanticsBinding, HitTestable {
        }
        /// RenderObject渲染树中所有节点的基类,定义了布局,绘制和合成相关的接口
        abstract class RenderBox extends RenderObject {
        }
        /// An image in the render tree.
        class RenderImage extends RenderBox {
        }
        /// A table where the columns and rows are sized to fit the contents of the cells.
        class RenderTable extends RenderBox {
        }
        /// Displays its children in a one-dimensional array.
        class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, FlexParentData>,
                                        RenderBoxContainerDefaultsMixin<RenderBox, FlexParentData>,
                                        DebugOverflowIndicatorMixin {
                                        }
         /// A render object that displays a paragraph of text
        class RenderParagraph extends RenderBox {
        }
        
    • 在Flutter界面渲染过程分为三个阶段:布局,绘制,合成,其中布局和绘制在Flutter框架中完成,合成交由Engine负责
      在这里插入图片描述

      • UI绘制流程
        • 1.运行动画,动画的结果会导致 Widget State 的改变;
        • 2.State Changes 触发 Flutter 生成一棵新的 Widget 树;
        • 3.Flutter 根据新/旧 Widget 树的差异更新 Render 树,重新排版更新界面布局;
        • 4.Flutter 根据新的 Render 树更新 Composited Layer(合成图层)的 Display List;
        • 5.输出新的图层树;
    • Widgets库

      • Flutter提供了非常丰富的控件,包括最基本的文件,图片,容器,输入框和动画等。在Flutter中“一切皆是控件”,通过组合,嵌套不同类型的控件可以构成任意功能,任意复杂度的界面,以下为widget库中重要的几个类:

      WidgetsBinding是widgets 层和Flutter引擎的胶水层widgetBinding
      在这里插入图片描述

      • Widget就是所有控件的基类,它本身的所有数据是只读的。RenderingObjectWidgets所有的实现类负责提供配置信息并创建具体的RenderObjectElement。widget的属性最好都是immutable。
      • Element是Flutter用来分离控件和真正渲染对象的中间层,控件用来描述对应的element属性,存放上下文,通过Element遍历视图树,Element同时持有Widget和RenderObject。控件重建后可能会复用同一个element。RenderObjectElement持有真正负责布局,绘制和碰撞测试(hit test)的RenderObject对象。
      • RenderObject:根据Widget的布局属性进行layout,paint Widget传入的内容。
        1. 为什么widget都是immutable?
          flutter界面开发是一种响应式编程,主张simple is fast,flutter设计的初衷希望数据变更时发送通知到对应的可变更节点(可能是一个StatefulWidget子节点,也可以是rootWidget),由上到下重新create widget树进行刷新,这种思路比较简单,不用关心数据变更会影响到哪些节点。
          2.widget重新创建,element树和RenderObject树是否也重新创建?
          widget只是一个配置数据结构,创建是非常轻量的,加上flutter团队对widget的创建/销毁做了优化,不用担心整个widget树重新创建所带来的性能问题,但是RenderObject就不一样了,RenderObject涉及到layout、paint等复杂操作,是一个真正渲染的view,整个view 树重新创建开销就比较大,所以答案是否定的。
  • Dart语言

    • Dart语言的重要理念
      • 放在变量中的所有东西都是一个对象,每个对象都是一个类的实例。即使是数字,功能, null也是对象。所有对象都从Object类继承。
      • 虽然Dart是强类型的,但类型注释是可选的,因为Dart可以推断类型。在上面的代码中,number 被推断为是类型的int。当你想明确地说没有类型时, 使用特殊类型dynamic。
      • Dart支持泛型类型,如List(整数列表)或List(任何类型的对象列表)。
      • Dart支持顶层函数(如main()),以及与类或对象绑定的函数(分别为静态方法和实例方法)。你也可以在函数中创建函数(嵌套函数或局部函数)。
      • Dart支持顶级变量以及绑定到类或对象(静态变量和实例变量)的变量。实例变量有时称为字段或属性。与Java,dart不具备关键字public,protected和private。如果标识符以下划线(_)开头,则它的库是私有的。有关详细信息,请参阅 库和可见性。
      • 标识符可以以字母或下划线(_)开头,然后是这些字符和数字的任意组合。有时候,重要的是某件事是一种表达式还是一种 声明,所以这两个词的确切含义很有帮助。
      • Dart工具可以报告两种问题:warnings 和errors。警告只是表明您的代码可能无法正常工作,但它们不会阻止您的程序执行。错误可以是编译时或运行时。编译时错误导致代码无法执行; 运行时错误导致 代码执行时引发异常。
      • Dart语言入门
4.Flutter 初体验
  • Flutter纵使千般好,纸上得来终觉浅。按照官网下载了Flutter SDK,使用Android Studio 3.3.2,使用了Github的下列教程代码 awesome-flutter的FlutterWhatsAppClone项目
    FlutterWhatsApp
    • pubspec.yaml
      • 依赖配置声明文件
         #在Flutter中,依赖包由Pub仓库管理,项目依赖配置在这个文件中声明即可,
        	#对于未发布在Pub仓库的插件可以使用git仓库地址或文件路径
        	name: flutterwhatsapp
        	description: A new Flutter project.
        	
        	dependencies:
        	  flutter:
        	    sdk: flutter
        	
        	  # The following adds the Cupertino Icons font to your application.
        	  # Use with the CupertinoIcons class for iOS style icons.
        	  cupertino_icons: ^0.1.0
        	  camera:
        	
        	dev_dependencies:
        	  flutter_test:
        	    sdk: flutter
        	
        	
        	# For information on the generic Dart part of this file, see the
        	# following page: https://www.dartlang.org/tools/pub/pubspec
        	
        	# The following section is specific to Flutter.
        	flutter:
        	
        	  # The following line ensures that the Material Icons font is
        	  # included with your application, so that you can use the icons in
        	  # the material Icons class.
        	  uses-material-design: true
        	
        	  # To add assets to your application, add an assets section, like this:
        	  # assets:
        	  #  - images/a_dot_burr.jpeg
        	  #  - images/a_dot_ham.jpeg
        	
        	  # An image asset can refer to one or more resolution-specific "variants", see
        	  # https://flutter.io/assets-and-images/#resolution-aware.
        	
        	  # For details regarding adding assets from package dependencies, see
        	  # https://flutter.io/assets-and-images/#from-packages
        	
        	  # To add custom fonts to your application, add a fonts section here,
        	  # in this "flutter" section. Each entry in this list should have a
        	  # "family" key with the font family name, and a "fonts" key with a
        	  # list giving the asset and other descriptors for the font. For
        	  # example:
        	  # fonts:
        	  #   - family: Schyler
        	  #     fonts:
        	  #       - asset: fonts/Schyler-Regular.ttf
        	  #       - asset: fonts/Schyler-Italic.ttf
        	  #         style: italic
        	  #   - family: Trajan Pro
        	  #     fonts:
        	  #       - asset: fonts/TrajanPro.ttf
        	  #       - asset: fonts/TrajanPro_Bold.ttf
        	  #         weight: 700
        	  #
        	  # For details regarding fonts from package dependencies, 
        	  # see https://flutter.io/custom-fonts/#from-packages
        
          ```
        
    • main.dart
      • app的入口文件
        import 'dart:async';
        
        import 'package:flutter/material.dart';
        import 'package:flutterwhatsapp/whatsapp_home.dart';
        import 'package:camera/camera.dart';
        
        List<CameraDescription> cameras;
        
        Future<Null> main() async {
          cameras = await availableCameras();
          runApp(new MyApp());
        }
        
        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return new MaterialApp(
              title: "WhatsApp",
              theme: new ThemeData(
                primaryColor: new Color(0xff075E54),
                accentColor: new Color(0xff25D366),
              ),
              debugShowCheckedModeBanner: false,
              home: new WhatsAppHome(cameras),
            );
          }
        }
        
    • whatsapp_home.dart
      • app主页
         import 'package:flutter/material.dart';
         import 'package:flutterwhatsapp/pages/call_screen.dart';
         import 'package:flutterwhatsapp/pages/camera_screen.dart';
         import 'package:flutterwhatsapp/pages/chat_screen.dart';
         import 'package:flutterwhatsapp/pages/status_screen.dart';
        
         class WhatsAppHome extends StatefulWidget {
           var cameras;
           WhatsAppHome(this.cameras);
         
           @override
           _WhatsAppHomeState createState() => new _WhatsAppHomeState();
         }
         
         class _WhatsAppHomeState extends State<WhatsAppHome>
             with SingleTickerProviderStateMixin {
           TabController _tabController;
         
           @override
           void initState() {
             super.initState();
             _tabController = new TabController(vsync: this, initialIndex: 1, length: 4);
           }
         
           @override
           Widget build(BuildContext context) {
             return new Scaffold(
               appBar: new AppBar(
                 title: new Text("WhatsApp"),
                 elevation: 0.7,
                 bottom: new TabBar(
                   controller: _tabController,
                   indicatorColor: Colors.white,
                   tabs: <Widget>[
                     new Tab(icon: new Icon(Icons.camera_alt)),
                     new Tab(text: "CHATS"),
                     new Tab(
                       text: "STATUS",
                     ),
                     new Tab(
                       text: "CALLS",
                     ),
                   ],
                 ),
                 actions: <Widget>[
                   new Icon(Icons.search),
                   new Padding(
                     padding: const EdgeInsets.symmetric(horizontal: 5.0),
                   ),
                   new Icon(Icons.more_vert)
                 ],
               ),
               body: new TabBarView(
                 controller: _tabController,
                 children: <Widget>[
                   new CameraScreen(widget.cameras),// 相机模块
                   new ChatScreen(),//聊天模块
                   new StatusScreen(),//状态模块
                   new CallsScreen(),//电话模块
                 ],
               ),
               floatingActionButton: new FloatingActionButton(
                 backgroundColor: Theme.of(context).accentColor,
                 child: new Icon(
                   Icons.message,
                   color: Colors.white,
                 ),
                 onPressed: () => print("open chats"),
               ),
             );
           }
         }
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值