• 《Flutter开发实战教程》

  • 价格:免费
  • 状态:全书已完结
  • 在读人数:20
  • 热度:1618
创建者
  • Cactus
  • 20 粉丝 39博客
内容简介

Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。

Flutter移动APP开发技术具有如下几个特点:

1.快速开发
Flutter的热重载可帮助您快速地进行测试、构建UI、添加功能并更快地修复错误。在iOS和Android模拟器或真机上可以在亚秒内重载,并且不会丢失状态。


2.富有表现力,漂亮的用户界面
使用Flutter内置美丽的Material Design和Cupertino(iOS风格)widget、丰富的motion API、平滑而自然的滑动效果和平台感知,为您的用户带来全新体验。


3.现代的,响应式框架
使用Flutter的现代、响应式框架,和一系列基础widget,轻松构建您的用户界面。使用功能强大且灵活的API(针对2D、动画、手势、效果等)解决艰难的UI挑战。


4.访问本地功能和SDK
通过平台相关的API、第三方SDK和原生代码让您的应用变得强大易用。 Flutter允许您复用现有的Java、Swift或ObjC代码,访问iOS和Android上的原生系统功能和系统SDK。

5.统一的应用开发体验
Flutter拥有丰富的工具和库,可以帮助您轻松地同时在iOS和Android系统中实现您的想法和创意。 如果您没有任何移动端开发体验,Flutter是一种轻松快捷的方式来构建漂亮的移动应用程序。 如果您是一位经验丰富的iOS或Android开发人员,则可以使用Flutter作为视图(View)层, 并可以使用已经用Java / ObjC / Swift完成的部分(Flutter支持混合开发)。

想要学习Flutter移动开发技术吗?那就从把我加入书架开始吧!

章节目录
  • 第一章 Flutter起步
  • 1.1 移动开发技术简介
  • 本节将主要介绍一下移动开发技术的进化历程,了解一下 Flutter 技术出现的背景。笔者认为,了解一门新技术出现的背景是非常重要的,因为只有了解之前是什么样的,才能理解为什么会是现在这样。#1.1.1
  • 1.2 初识 Flutter
  • 1.2.1 Flutter 简介 Flutter 是 Google 推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter 提供了丰富的组件、接口,开发者可以很快地为 Flutter 添加
  • 1.3 搭建Flutter开发环境
  • 工欲善其事必先利其器,本节首先会分别介绍一下在Windows和macOS下Flutter SDK的安装,然后再介绍一下配IDE和模拟器的使用。1.3.1 安装Flutter 由于Flutter会同时构建Android和IOS两个平台的发布包,所以Flutter同时依赖Android SDK和iOS
  • 1.4 Dart语言简介
  • 在之前我们已经介绍过 Dart 语言的相关特性,读者可以翻看一下,如果读者已经熟悉 Dart 语法,可以跳过本节,如果你还不了解 Dart,也不用担心,按照笔者经验,如果你有过其他编程语言经验(尤其是 Java 或 JavaScript)的话会非常容易上手 Dart。当然,如果你是 iOS 开发者,也不用担心,Dart 中也有
  • 第二章 第一个Flutter应用
  • 2.1 用Flutter写个计数器
  • 用 Android Studio 和 VS Code 创建的 Flutter 应用模板默认是一个简单的计数器示例。本节先仔细讲解一下这个计数器 Demo 的源码,让读者对 Flutter 应用程序结构有个基本了解,然后在随后的小节中将会基于此示例,一步一步添加一些新的
  • 2.2 Widget 简介
  • 2.2.1 Widget 概念 在前面的介绍中,我们知道在Flutter中几乎所有的对象都是一个 widget 。与原生开发中“控件”不同的是,Flutter 中的 widget 的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的
  • 2.3 状态管理
  • 响应式的编程框架中都会有一个永恒的主题——“状态(State)管理”,无论是在 React/Vue(两者都是支持响应式编程的 Web 开发框架)还是 Flutter 中,他们讨论的问题和解决的思想都是一致的。所以,如果你对React/Vue的状态管理有了解,可以跳过本节。言归正传,我们想一个问题,StatefulW
  • 2.4 路由管理
  • 路由(Route)在移动开发中通常指页面(Page),这跟 Web 开发中单页应用的 Route 概念意义是相同的,Route 在 Android中 通常指一个 Activity,在 iOS 中指一个 ViewController。所谓路由管理,就是管理页面之间如何跳转,通常也可被称为导航管理。Fl
  • 2.5 包管理
  • 在软件开发中,很多时候有一些公共的库或 SDK 可能会被很多项目用到,因此,将这些代码单独抽到一个独立模块,然后哪个项目需要使用时再直接集成这个模块,便可大大提高开发效率。很多编程语言或开发工具都支持这种“模块共享”机制,如 Java
  • 2.6 资源管理
  • Flutter APP 安装包中会包含代码和 assets(资源)两部分。Assets 是会打包到程序安装包中的,可在运行时访问。常见类型的 assets 包括静态数据(例如JSON文件)、配置文件、图标和图片等。指定 assets 和包管理一样,Flutter 也使用pubspec.yaml (opens new window)文件来管理应用程序所需的资源,举个例子: flutter
  • 2.7 调试Flutter应用
  • 日志与断点 debugger() 声明 当使用Dart Observatory(或另一个Dart调试器,例如IntelliJ IDE中的调试器)时,可以使用该debugger()语句插入编程式断点。要使用这个,你必须添加import 'dart:developer';到相关文件顶部。debugger()语句采用一个可选when参数,我们可以指定该参数仅在特定条
  • 2.8 Flutter异常捕获
  • 在介绍Flutter异常捕获之前必须先了解一下Dart单线程模型,只有了解了Dart的代码执行流程,我们才能知道该在什么地方去捕获异常。2.8.1 Dart单线程模型 在 Java 和 Objective-C(以下简称“OC”)中,如果程序发生异常且没有被捕获,那么程序将会终止,但是这在Dart或JavaScript中则不会!究其原因,这和它们的运行机制有关系。Ja
  • 第三章 基础组件
  • 3.1 文本及样式
  • 3.1.1 Text Text 用于显示简单样式文本,它包含一些控制文本显示样式的一些属性,一个简单的例子如下: Text("Hello world",textAlign: TextAlign.left, );Text("Hello world! I'm Jack. "*4,maxLines:
  • 3.2 按钮
  • Material 组件库中提供了多种按钮组件如ElevatedButton、TextButton、OutlineButton等,它们都是直接或间接对RawMaterialButton组件的包装定制,所以他们大多数
  • 3.3 图片及ICON
  • 3.3.1 图片 Flutter 中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProvider ImageProvider 是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvider ,如AssetImage是实现
  • 3.4 单选开关和复选框
  • Material 组件库中提供了 Material 风格的单选开关Switch和复选框Checkbox,虽然它们都是继承自StatefulWidget,但它们本身不会保存当前选中状态,选中状态都是由父组件来管理的。当Switch或Checkbox被点击时,会触发它们的onC
  • 3.5 输入框及表单
  • Material 组件库中提供了输入框组件TextField和表单组件Form。下面我们分别介绍一下。3.5.1 TextField TextField用于文本输入,它提供了很多属性,我们先简单介绍一下主要属性的作用,然后通过几个示例来演示一下
  • 3.6 进度条
  • Material 组件库中提供了两种进度指示器:LinearProgressIndicator和CircularProgressIndicator,它们都可以同时用于精确的进度指示和模糊的进度指示。精确进度通常用于任务进度可以计算和预估的情况,比如文件下载;而模糊进度则用户任务进度无法准确获得的情况,
  • 第四章 布局类组件简介
  • 4.1 布局类组件简介
  • 简介 布局类组件都会包含一个或多个子组件,不同的布局类组件对子组件排列(layout)方式不同。布局类组件就是指直接或间接继承(包含)SingleChildRenderObjectWidget 和MultiChildRenderObjectWidget的Widget,它们一般都会有一个child或children属性用于接收子 Widget。我们看一下继承关系 Widget > Rende
  • 4.2 布局原理与约束(constraints)
  • 尺寸限制类容器用于限制容器大小,Flutter中提供了多种这样的容器,如ConstrainedBox、SizedBox、UnconstrainedBox、AspectRatio 等,本节将介绍一些常用的。Flutter 中有两种布局模型: 1.基于
  • 4.3 线性布局(Row和Column)
  • 所谓线性布局,即指沿水平或垂直方向排列子组件。Flutter 中通过Row和Column来实现线性布局,类似于Android 中的LinearLayout控件。Row和Column都继承自Flex,我们将在弹性布局一节中详细介绍Flex。主轴
  • 4.4 弹性布局(Flex)
  • 弹性布局允许子组件按照一定比例来分配父容器空间。弹性布局的概念在其它UI系统中也都存在,如 H5 中的弹性盒子布局,Android中 的FlexboxLayout等。Flutter 中的弹性布局主要通过Flex和E
  • 4.5 流式布局
  • 在介绍 Row 和 Colum 时,如果子 widget 超出屏幕范围,则会报溢出错误,如: Row(children: <Widget>[Text("xxx"*100)],
  • 4.6 层叠布局 Stack、Positioned
  • 层叠布局和 Web 中的绝对定位、Android 中的 Frame 布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。层叠布局允许子组件按照代码中声明的顺序堆叠起来。Flutter中使用Stack和Po
  • 4.7 对齐与相对定位(Align)
  • 在上一节中我们讲过通过Stack和Positioned,我们可以指定一个或多个子元素相对于父元素各个边的精确偏移,并且可以重叠。但如果我们只想简单的调整一个子元素在父元素中的位置的话,使用Align组件会更简单一些。4.7.1 Align Align
  • 4.8 LayoutBuilder、AfterLayout
  • 4.8.1 LayoutBuilder 通过 LayoutBuilder,我们可以在布局过程中拿到父组件传递的约束信息,然后我们可以根据约束信息动态的构建不同的布局。比如我们实现一个响应式的 Column 组件 ResponsiveColumn,它的
  • 第五章 容器类组件
  • 5.1 填充
  • 5.1 填充(Padding) Padding可以给其子节点添加填充(留白),和边距效果类似。我们在前面很多示例中都已经使用过它了,现在来看看它的定义: Padding({...EdgeInsetsGeometry padding,Widget child, })
  • 5.2 尺寸限制类容器
  • 尺寸限制类容器用于限制容器大小,Flutter中提供了多种这样的容器,如ConstrainedBox、SizedBox、UnconstrainedBox、AspectRatio 等,本节将介绍一些常用的。尺寸限制类容器涉及到Flutter 布局流程 ,确定子组件大小的步骤为: 1.上层组件向下层组件传递约束条件。 2.下层组件确定自己的大小,然后告
  • 5.3 装饰容器DecoratedBox
  • DecoratedBox可以在其子组件绘制前(或后)绘制一些装饰(Decoration),如背景、边框、渐变等。DecoratedBox定义如下: const DecoratedBox({Decoration decoration,DecorationPosition position = DecorationPositi
  • 5.4 变换(Transform)
  • Transform可以在其子组件绘制时对其应用一些矩阵变换来实现一些特效。Matrix4是一个4D矩阵,通过它我们可以实现各种矩阵操作,下面是一个例子: Container(color: Colors.black,child: Transform(alignment: Alignme
  • 5.5 Container
  • 我们在前面的章节示例中多次用到过Container组件,本节我们就详细介绍一下Container组件。Container是一个组合类容器,它本身不对应具体的RenderObject,它是DecoratedBox、ConstrainedBox
  • 5.6 剪裁(Clip)
  • Flutter中提供了一些剪裁函数,用于对组件进行剪裁。下面看一个例子: import 'package:flutter/material.dart';class ClipTestRoute extends StatelessW
  • 5.7 空间适配 FittedBox
  • 5.7.1 FittedBox 子组件大小超出了父组件大小时,如果不经过处理的话 Flutter 中就会显示一个溢出警告并在控制台打印错误日志,比如下面代码会导致溢出: Padding(padding: const Ed
  • 5.8 Scaffold
  • Material 组件库提供了丰富多样的组件,本节介绍一下最常用的 Scaffold 组件,其余的读者可以自行查看文档或 Flutter Gallery 中 Material 组件部分的示例。Flutter Gallery是Flutter官方提供的Flutter Demo,源码位于flutter源码中的examples目录下,笔者强烈建议用户将F
  • 第六章 可滚动组件
  • 6.1 可滚动组件简介
  • Flutter 中有两种布局模型: 1.基于 RenderBox 的盒模型布局。 2.基于 Sliver ( RenderSliver ) 按需加载列表布局。 前面章节的布局类型都是第一种,本节主要介绍一下第二种布局。通常可滚动组件的子组件可能会非常多、占用的总高度也会非常大;如果要一次性将子组件全部构建出将会非常昂贵!为此,Flutter中提出一个Sliv
  • 6.2 SingleChildScrollView
  • SingleChildScrollView类似于Android中的ScrollView,它只能接收一个子组件,定义如下: SingleChildScrollView({this.scrollDirection = Axis.vertical, //滚动方向,默认是垂直方向this.reverse = false, this.padding,
  • 6.3 ListView
  • ListView是最常用的可滚动组件之一,它可以沿一个方向线性排布所有子组件,并且它也支持列表项懒加载(在需要时才会创建)。我们看看ListView的默认构造函数定义: ListView({... //可滚动widget公共参数Axis scrollDirection = Axis.vertical,bool reverse = false,ScrollController
  • 6.4 滚动监听及控制
  • 在前几节中,我们介绍了Flutter中常用的可滚动组件,也说过可以用ScrollController来控制可滚动组件的滚动位置,本节先介绍一下ScrollController,然后以ListView为例,展示一下ScrollController的具体用法。最后,再介绍一下路由切换时如何来保存滚动位置。6.4.1 ScrollController ScrollControll
  • 6.5 AnimatedList
  • AnimatedList 和 ListView 的功能大体相似,不同的是, AnimatedList 可以在列表中插入或删除节点时执行一个动画,在需要添加或删除列表项的场景中会提高用户体验。AnimatedList 是一个 Sta
  • 6.6 GridView
  • GridView可以构建一个二维网格列表,其默认构造函数定义如下:GridView({Key? key,Axis scrollDirection = Axis.vertical,bool reverse = false,ScrollController? co
  • 6.7 PageView与页面缓存
  • 6.7.1 PageView 如果要实现页面切换和 Tab 布局,我们可以使用 PageView 组件。需要注意,PageView 是一个非常重要的组件,因为在移动端开发中很常用,比如大多数 App 都包含 Tab 换页效果、图片轮动以及
  • 6.8 可滚动组件子项缓存 KeepAlive
  • 本节将介绍一种在可滚动组件中缓存指定子项的通用方案。首先回想一下,在介绍 ListView 时,有一个addAutomaticKeepAlives 属性我们并没有介绍,如果addAutomaticKeepAlives 为 true,则 ListView 会为每一个列表项添加一个
  • 6.9 TabBarView
  • TabBarView 是 Material 组件库中提供了 Tab 布局组件,通常和 TabBar 配合使用。6.9.1 TabBarView TabBarView 封装了 PageView,它的构造方法很简单TabBarView({Key? key,required this.childre
  • 6.10 CustomScrollView 和 Slivers
  • 6.10.1 CustomScrollView 前面介绍的 ListView、GridView、PageView 都是一个完整的可滚动组件,所谓完整是指它们都包括Scrollable 、 Viewport 和 Sliver。假如我们想要在一个页面中,同时包含多个可滚动组件,且使它们的
  • 6.11 自定义 Sliver
  • 本节将通过自定义两个Sliver,来说明Sliver 布局协议和自定义 Sliver 的具体过程。6.11.1 Sliver 布局协议 Sliver 的布局协议如下: 1.Viewport 将当前布局和配置信息通过 SliverConstraints 传递给 Sliver。 2.Sliver 确定自身的位置、绘制等信息,保存在 geometry 中(一个 SliverGeometry 类
  • 6.12 嵌套可滚动组件 NestedScrollView
  • 6.12.1 NestedScrollView 上一节中,我们知道 CustomScrollView 只能组合 Sliver,如果有孩子也是一个可滚动组件(通过 SliverToBoxAdapter 嵌入)且它们的滑动方向一致时便不能正常工作。为了解
  • 第七章 功能型组件
  • 7.1 导航返回拦截(WillPopScope)
  • 为了避免用户误触返回按钮而导致 App 退出,在很多 App 中都拦截了用户点击返回键的按钮,然后进行一些防误触判断,比如当用户在某一个时间段内点击两次时,才会认为用户是要退出(而非误触)。Flutter中可以通过WillPopScope来实现返回按钮拦截,我们看看WillPopScope的默认构造函数: const WillPopSc
  • 7.2 数据共享(InheritedWidget)
  • InheritedWidget是 Flutter 中非常重要的一个功能型组件,它提供了一种在 widget 树中从上到下共享数据的方式,比如我们在应用的根 widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子widget 中来获取该共享的数据!这个特性在一些需要在整个 widget
  • 7.3 跨组件状态共享(Provider)
  • 在 Flutter 开发中,状态管理是一个永恒的话题。一般的原则是:如果状态是组件私有的,则应该由组件自己管理;如果状态要跨组件共享,则该状态应该由各个组件共同的父元素来管理。对于组件私有的状态管理很好理解,但对于跨组件共享的状态,管理的方式就比较多了,如使用全局事件总线EventBus(将在下一章中介绍),它是一个观察者模式的实现,通过它就可以实
  • 7.4 颜色和主题
  • 7.4.1 颜色 在介绍主题前我们先了解一些Flutter中的 Color 类。Color 类中颜色以一个 int 值保存,我们知道显示器颜色是由红、绿、蓝三基色组成,每种颜色占8比特,存储结构如下:上面表格中的的字段在 Color 类中都有对应的属性,而Color中的众多方法也就是操作这些属性的,由于大多比较简
  • 7.5 ValueListenableBuilder
  • InheritedWidget 提供一种在 widget 树中从上到下共享数据的方式,但是也有很多场景数据流向并非从上到下,比如从下到上或者横向等。为了解决这个问题,Flutter 提供了一个 ValueListenableBuilder 组件,它的功能是监听一个数据源,如果数据源发生变化,则会重新执行其 builder,定义如下: const ValueListenableBuil
  • 7.6 异步UI更新(FutureBuilder、StreamBuilder)
  • 很多时候我们会依赖一些异步数据来动态更新UI,比如在打开一个页面时我们需要先从互联网上获取数据,在获取数据的过程中我们显示一个加载框,等获取到数据时我们再渲染页面;又比如我们想展示Stream(比如文件流、互联网数据接收流)的进度。当然,通过 StatefulWidget 我们完全可以实现上述这些功能。但由于在实际开发中依
  • 7.7 对话框详解
  • 本节将详细介绍一下Flutter中对话框的使用方式、实现原理、样式定制及状态管理。7.7.1 使用对话框 对话框本质上也是UI布局,通常一个对话框会包含标题、内容,以及一些操作按钮,为此,Material库中提供了一些现成的对话框组件来用
  • 第八章 事件处理与通知
  • 8.1 原始指针事件处理
  • 本节先来介绍一下原始指针事件(Pointer Event,在移动设备上通常为触摸事件),下一节再介绍手势处理。在移动端,各个平台或UI系统的原始指针事件模型基本都是一致,即:一次完整的事件分为三个阶段:手指按下、手指移动、和手指抬起,而更高级别的手势(如点击、双击、拖动等)都是基于这些原始事件的。当指针按下时,Flutter会对应用程序执行命中测试(Hit Test),以确定指
  • 8.2 手势识别
  • 本节先介绍一些Flutter中用于处理手势的GestureDetector和GestureRecognizer,然后再仔细讨论一下手势竞争与冲突问题。8.2.1 GestureDetector GestureDetector是一个用于手势识别的功能性组件,我们通过它可以来识别各种手势。GestureDetector 内部封装了 Listener,用以识别语义化的手势,接下来我们详
  • 8.3 Flutter事件机制
  • 8.3.1 Flutter 事件处理流程 Flutter 事件处理流程主要分两步,为了聚焦核心流程,我们以用户触摸事件为例来说明: 1.命中测试:当手指按下时,触发 PointerDownEvent 事件,按照深度优先遍历当前渲染(render object)树,对每一个渲染对象进行“命中测试”(hit test),如果命中测试通过,则该渲染对象会被添加到一个 HitTest
  • 8.4 手势原理与手势冲突
  • 8.4.1 手势识别原理 手势的识别和处理都是在事件分发阶段的,GestureDetector 是一个 StatelessWidget, 包含了 RawGestureDetector,我们看一下它的 build 方法实现: @override Widget build(BuildContext context) {final gestures
  • 8.5 事件总线
  • 在 App 中,我们经常会需要一个广播机制,用以跨页面事件通知,比如一个需要登录的 App 中,页面会关注用户登录或注销事件,来进行一些状态更新。这时候,一个事件总线便会非常有用,事件总线通常实现了订阅者模式,订阅者模式包含发布者和订阅者两种角色,可以通过事件总线来触发事件和监听事件,本节我们实现一个简单的
  • 8.6 通知 Notification
  • 通知(Notification)是Flutter中一个重要的机制,在widget树中,每一个节点都可以分发通知,通知会沿着当前节点向上传递,所有父节点都可以通过NotificationListener来监听通知。Flutter中将这种由子向父的传递通
  • 第九章 动画
  • 9.1 Flutter动画简介
  • 9.1 Flutter动画简介 在任何系统的UI框架中,动画实现的原理都是相同的,即:在一段时间内,快速地多次改变UI外观;由于人眼会产生视觉暂留,所以最终看到的就是一个“连续”的动画,这和电影的原理是一样的。我们将UI的一次改变称为一个动画帧,对应一次屏幕刷新,而决定动画流畅度的一个重要指标就是帧率FPS(Frame Per Second),即每秒
  • 9.2 动画基本结构及状态监听
  • 9.2.1 动画基本结构 在Flutter中我们可以通过多种方式来实现动画,下面通过一个图片逐渐放大示例的不同实现来演示Flutter中动画的不同实现方式的区别。#基础版本 下面我们演示一下最基础的动画实现方式: class ScaleA
  • 9.3 自定义路由切换动画
  • 我们在第二章“路由管理”一节中讲过:Material组件库中提供了一个MaterialPageRoute组件,它可以使用和平台风格一致的路由切换动画,如在iOS上会左右滑动切换,而在Android上会上下滑
  • 9.4 Hero动画
  • 自实现Hero动画 比如现在有一个头像组件,初始的时候是一个圆形的小图,我们想实现点击后查看大图的功能,为了有较好的体验,小图变成大图和大图变回小图时我们分别执行一个“飞行”过渡动画,效果如下所示:要实现上面的动画效果,最简单的方式就是使用 Flutter 的 Hero 动画,但是为了让读者理解 Hero
  • 9.5 交织动画
  • 有些时候我们可能会需要一些复杂的动画,这些动画可能由一个动画序列或重叠的动画组成,比如:有一个柱状图,需要在高度增长的同时改变颜色,等到增长到最大高度后,我们需要在X轴上平移一段距离。可以发现上述场景在不同阶段包含了多种动画,要实现这种效果,使用交织动画(Stagger Animation)会非常简单。交织动画需要注意以下几点: 1.要创建
  • 9.6 动画切换组件(AnimatedSwitcher)
  • 实际开发中,我们经常会遇到切换UI元素的场景,比如Tab切换、路由切换。为了增强用户体验,通常在切换时都会指定一个动画,以使切换过程显得平滑。Flutter SDK组件库中已经提供了一些常用的切换组件,如PageView、TabView等,但是,这些组件并不能覆盖全部的需求场景,为此,Flutter SDK中提供了一个AnimatedSwitcher组件,
  • 9.7 动画过渡组件
  • 为了表述方便,本书约定,将在Widget属性发生变化时会执行过渡动画的组件统称为”动画过渡组件“,而动画过渡组件最明显的一个特征就是它会在内部自管理AnimationController。我们知道,为了方便使用者可以自定义动画的曲线、执行时长、方向等,在前面介绍过的动画封装方法中,通常都需
  • 第十章 自定义组件
  • 10.1 自定义组件方法简介
  • 当Flutter提供的现有组件无法满足我们的需求,或者我们为了共享代码需要封装一些通用组件,这时我们就需要自定义组件。在Flutter中自定义组件有三种方式:通过组合其它组件、自绘和实现RenderObject。本节我们先分别介绍一下这三种方式的特点,后面章节中则详细介绍它们的细
  • 10.2 组合现有组件
  • 在Flutter中页面UI通常都是由一些低级别组件组合而成,当我们需要封装一些通用组件时,应该首先考虑是否可以通过组合其它组件来实现,如果可以,则应优先使用组合,因为直接通过现有组件拼装会非常简单、灵活、高效。示例:自定义渐变按钮 Flutter Material组件库中的按钮默认不支持渐变背景,为了实现渐变
  • 10.3 组合实例:TurnBox
  • 我们之前已经介绍过RotatedBox,它可以旋转子组件,但是它有两个缺点:一是只能将其子节点以90度的倍数旋转;二是当旋转的角度发生变化时,旋转角度更新过程没有动画。本节我们将实现一个TurnBox组件,
  • 10.4 CustomPaint 与 Canvas
  • 对于一些复杂或不规则的UI,我们可能无法通过组合其它组件的方式来实现,比如我们需要一个正六边形、一个渐变的圆形进度条、一个棋盘等。当然,有时候我们可以使用图片来实现,但在一些需要动态交互的场景静态图片也是实现不了的,比如要实现一个手写输入面板,这时,我们就需要来自己绘制UI外观。几乎所有的UI系统都会提供一个自绘UI的接口,这个接口通常会提供一
  • 10.5 自绘实例:圆形背景渐变进度条
  • 本节我们实现一个圆形背景渐变进度条,它支持: 1.支持多种背景渐变色。 2.任意弧度;进度条可以不是整圆。 3.可以自定义粗细、两端是否圆角等样式。 可以发现要实现这样的一个进度条是无法通过现有组件组合而成的,所以我们通过自绘方式
  • 10.6 自绘组件:CustomCheckbox
  • Flutter 自带的 Checkbox 组件是不能自由指定大小的,本节我们通过自定义一个可以自由指定大小的 CustomCheckbox 组件来演示如何通过定义 RenderObject 的方式来自定义组件(而不是通过组合)。1.有选中和未选中两
  • 10.7 自绘组件: DoneWidget
  • 上一节中我们通过 CustomCheckbox 演示了如何通过自定义 RenderObject 的方式来进行UI绘制、动画调度和事件处理。本节再通过一个实例来巩固换一下。本节的我们将实现一个 DoneWidget,它可以在创建时执行一个打勾动画,效果如下:todo补图: class DoneWidget extends LeafRenderObjectWidget {Do
  • 10.8 水印实例: 文本绘制与离屏渲染
  • 本节将通过实现一个水印组件来介绍一下如何绘制文本以及如何进行离屏渲染。在实际场景中,大多数情况下水印是要铺满整个屏幕的,如果不需要铺满屏幕,通常直接用组件组合即可实现,本节我们主要讨论的是需要铺满屏幕的水印。10.8.1 水印组件Water
  • 第十一章 文件操作与网络请求
  • 11.1 文件操作
  • Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的,不过和 Dart VM 相比,Flutter 有一个重要差异是文件系统路径不同,这是因为Dart VM 是运行在 PC 或服务器操作系统下,而 Flutter 是运行在移动操作系统中,他们
  • 11.2 通过HttpClient发起HTTP请求
  • Dart IO库中提供了用于发起Http请求的一些类,我们可以直接使用HttpClient来发起请求。使用HttpClient发起请求分为五步:1.创建一个HttpClient:HttpClient httpClient = HttpCl
  • 11.3 Http请求-Dio http库
  • 通过上一节介绍,我们可以发现直接使用HttpClient发起网络请求是比较麻烦的,很多事情得我们手动处理,如果再涉及到文件上传/下载、Cookie管理等就会非常繁琐。幸运的是,Dart社区有一些第三方http请求库,用它们来发起http请求将会简单的多,本节我们介绍一下目前人气较高的di
  • 11.4 实例:Http分块下载
  • 本节将通过一个“Http分块下载”的示例演示一下dio的具体用法。 原理 Http协议定义了分块传输的响应header字段,但具体是否支持取决于Server的实现,我们可以指定请求头的"range"字段来验证服务器是否支持分块传输。例如,我们可以利用cur
  • 11.5 使用WebSockets
  • Http协议是无状态的,只能由客户端主动发起,服务端再被动响应,服务端无法向客户端主动推送内容,并且一旦服务器响应结束,链接就会断开(见注解部分),所以无法进行实时通信。WebSocket协议正是为解决客户端与服务
  • 11.6 使用Socket API
  • 我们之前介绍的 Http 协议和 WebSocket 协议都属于应用层协议,除了它们,应用层协议还有很多如:SMTP、FTP 等,这些应用层协议的实现都是通过 Socket API 来实现的。其实,操作系统中提供的原生网络请求 API 是标准的,在 C 语言的 Socket 库中,它主要提供了端到端建立链接和
  • 11.7 Json转Dart Model类
  • 在实战中,后台接口往往会返回一些结构化数据,如 JSON、XML 等,如之前我们请求 Github API 的示例,它返回的数据就是 JSON 格式的字符串,为了方便我们在代码中操作 JSON,我们先将 JSON 格式的字符串转为 Dart 对象,这个可以通过 dart:convert 中内置
  • 第十二章 国际化
  • 12.1 让App支持多语言
  • 如果我们的应用要支持多种语言,那么我们需要“国际化”它。这意味着我们在开发时需要为应用程序支持的每种语言环境设置“本地化”的一些值,如文本和布局。Flutter SDK已经提供了一些组件和类来帮助我们实现国际化,下面我们来介绍一下Flutter中实现国际化的步骤。接下来我们以MaterialApp类为入口的应用来说明如何支持国际化。 大多数应用
  • 12.2 实现Localizations
  • 前面讲了Material组件库如何支持国际化,本节我们将介绍一下我们自己的UI中如何支持多语言。根据上节所述,我们需要实现两个类:一个Delegate类一个Localizations类,下面我们通过一个实例说明。实现Localizations类 我们已经知道Loca
  • 12.3 使用Intl包
  • 使用Intl (opens new window)包我们不仅可以非常轻松的实现国际化,而且也可以将字符串文本分离成单独的文件,方便开发人员和翻译人员分工协作。为了使用Intl (opens new w
  • 12.4 国际化常见问题
  • 本节主要解答一下在国际化中常见的问题。默认语言区域不对 在一些非大陆行货渠道买的一些Android和iOS设备,会出现默认的Locale不是中文简体的情况。这属于正常现象,但是为了防止设备获取的Locale与实际的地区不一
  • 第十三章 Flutter核心原理
  • 13.1 Flutter UI 框架(Framework)
  • 在本书的开始,我们讲过 Flutter 从上到下分为框架层、引擎层和嵌入层三层。也说过开发者基本上都是与框架层打交道,本章将深入介绍一下 Flutter 框架层的原理,在此之前,我们先看看更广义的UI框架指的是什么?解决了什么问题?术语UI框架(UI Framework)特指:基于一个平台,在此平台上
  • 13.2 Element、BuildContext和RenderObject
  • 14.2.1 Element 在“Widget简介”一节,我们介绍了Widget和Element的关系,我们知道最终的UI树其实是由一个个独立的Element节点构成。我们也说过组件最终的Layout、渲染都是通过RenderObject来完成的,从创建到渲染的大体流程是:根据Widget生成Element,然后创建相应的RenderObject并关联到Element.rend
  • 13.3 Flutter启动流程和渲染管线
  • 本节我们会先介绍一下Flutter的启动流程,然后再介绍一下 Flutter 的 rendering pipeline (渲染管线)。14.3.1 启动 Flutter的入口在"lib/main.dart"的main()函数中,它是Dart应用程序的起点。在Flutter应用中,main()函数最简单的实现如下: void main() => runApp
  • 13.4 布局(Layout)过程
  • Layout(布局)过程主要是确定每一个组件的布局信息(大小和位置),Flutter 的布局过程如下: 1.父节点向子节点传递约束(constraints)信息,限制子节点的最大和最小宽高。 2.子节点根据约束信息确定自己的大小(size)。 3.父节点根据特定布局规则(不同布局组件会有不同的布局算法)确定每一个子节点在父节点布局空间中的位
  • 13.5 绘制(一)绘制原理及Layer
  • 14.5.1 Flutter 绘制原理 Flutter中和绘制相关的对象有三个,分别是Canvas、Layer 和 Scene: Canvas:封装了Flutter Skia各种绘制指令,比如画线、画圆、画矩形等指令。 Layer:分为容器类和绘制类两种;暂时可以理解为是绘制产物的载体,比
  • 13.6 绘制(二)组件树绘制流程
  • 绘制相关实现在渲染对象 RenderObject 中,RenderObject 中和绘制相关的主要属性有: .layer .isRepaintBoundary(类型bool) .needsCompositing (类型
  • 13.7 绘制(三)Layer 实例
  • 本节通过优化之前“绘制棋盘示例“来像大家展示如何在自定义组件中使用Layer。14.7.1 我们之前绘制棋盘示例是使用的CustomPaint组件,然后再painter的paint方法中同时实现了绘制棋盘和棋子,实际上这里可以有一个优化,因为棋盘是不会变化的,所以理想的方式就是当绘制区域不发生变化时,棋盘
  • 13.8 绘制(四)Compositing
  • 本节我们来介绍一下 flushCompositingBits()。现在,我们再来回顾一下Flutter的渲染管线: void drawFrame(){pipelineOwner.flushLayout();pipelineOwner.flushComposi
  • 第十四章 一个完整的Flutter应用
  • 14.1 Github客户端示例
  • 本章新建一个Flutter工程,实现一个简单的Github客户端。这个实例的主要目标有两个: 1.带领读者了解如何使用Flutter来开发一个完整APP,了解Flutter应用开发流程及工程结构等。2.对前面章节
  • 14.2 Flutter APP代码结构
  • 我们先来创建一个全新的Flutter工程,命名为"github_client_app";创建新工程的步骤视读者使用的编辑器而定,都比较简单,在此不再赘述。创建完成后,工程结构如下: github_client_app ├── android ├── ios ├── l
  • 14.3 Model类定义
  • 本节我们先梳理一下APP中将用到的数据,然后生成相应的Dart Model类。Json文件转Dart Model的方案采用前面介绍过的 json_model 包方案Github账号信息 登录Github后,我们需要获取当前登录者的Github账号信息,Github API接口返回Json结构如下: {"login": "octo
  • 14.4 全局变量及共享状态
  • 应用程序中通常会包含一些贯穿APP生命周期的变量信息,这些信息在APP大多数地方可能都会被用到,比如当前用户信息、Local信息等。在Flutter中我们把需要全局共享的信息分为两类:全局变量和共享状态。全局变量就是单纯指会贯穿整个APP生命周
  • 14.5 网络请求封装
  • 本节我们会基于前面介绍过的dio网络库封装APP中用到的网络请求接口,并同时应用一个简单的缓存策略。下面我们先介绍一下网络接口缓存原理,然后再封装APP的业务请求接口。15.5.1 网络接口缓存 由于在国内访问Github服务器速度较慢,所以我们应用一些简单的缓存策略:将请求的url作为key,对请求的返回值在一个指定时间
  • 14.6 APP入口及主页
  • 本节来介绍一下APP入口及首页。15.6.1 APP入口 main函数为APP入口函数,实现如下: void main() => Global.init().then((e) => runApp(MyApp())); 初始化完成后才会加载UI(MyApp),MyApp 是应用的入口Widget,实现如下: class MyApp extends StatelessWidg
  • 14.7 登录页
  • 我们说过Github有多种登录方式,为了简单起见,我们只实现通过用户名和密码登录。在实现登录页时有四点需要注意: 1.可以自动填充上次登录的用户名(如果有)。 2.为了防止密码输入错误,密码框应该有开关可以看明文。 3.用户名或密码字段在调用登录
  • 14.8 多语言和多主题
  • 本实例APP中语言和主题都是可以设置的,而两者都是通过ChangeNotifierProvider来实现的:我们在main函数中使用了Consumer2,依赖了ThemeModel和LocaleModel,因此,当我们在语言和主题设置页更该当前的配置后,Consumer2的builder都会重新执行,构建一个新的MaterialApp,所以修改会
读者评论
  • 你还没登录,点击这里
  • 本书评论
最近这些人在读这本书