目录
7.1.1 StatefulWidget 与 setState
7.1.4 Bloc(Business Logic Component)
9.2.1 基于 Tween 和 AnimationController
一、Flutter 是什么?为何值得学?
在移动应用开发的浩瀚宇宙中,Flutter 宛如一颗冉冉升起的新星,吸引着无数开发者的目光。那么,Flutter 究竟是什么呢?简单来说,Flutter 是 Google 开源的一款移动 UI 框架 ,它就像是一个超级魔法师,能让开发者仅用一套代码库,便施展出构建在 iOS、Android、Web、桌面甚至嵌入式平台上精美应用的神奇魔法。
回溯其诞生背景,随着移动互联网的迅猛发展,开发者们渴望一种更高效、更灵活的开发方式,以打破传统开发模式的束缚,Flutter 应运而生。它摆脱了对原生控件的依赖,采用自绘引擎 Skia,犹如一位技艺精湛的画师,亲手勾勒出应用的每一个像素,为开发者带来前所未有的掌控力。
Flutter 的优势可谓熠熠生辉。跨平台特性是其闪耀的光环之一,开发者再也无需为 iOS 和 Android 分别编写大量重复代码,一套代码轻松实现多端部署,大大缩短了开发周期,降低了开发成本。想象一下,你只需撰写一次代码,就能让应用在不同平台上华丽登场,这是何等的高效!
在性能表现上,Flutter 也毫不逊色。它直接将代码编译成机器码,充分释放 GPU 的强大图形加速能力,使应用的运行如丝般顺滑,媲美原生应用。以一个电商应用为例,在商品列表的加载和滑动过程中,Flutter 能够快速渲染界面,让用户仿佛置身于真实的购物场景,流畅的交互体验令人陶醉。
丰富的 UI 组件库则是 Flutter 送给开发者的又一份厚礼。从简洁大方的按钮,到绚丽多彩的动画效果,再到复杂精致的布局,Flutter 提供了琳琅满目的组件,满足各种创意需求。借助这些组件,开发者可以轻松搭建出独具特色的用户界面,为用户带来视觉盛宴。
热重载功能更是让 Flutter 在开发效率上一骑绝尘。在开发过程中,开发者修改代码后,无需漫长的重新编译和启动过程,瞬间就能看到更改后的效果,如同拥有了时光加速器,极大地提升了开发效率,让开发过程充满乐趣。
学习 Flutter,无疑是踏上了一条通往未来的光明之路。在当今数字化时代,跨平台开发的需求与日俱增,掌握 Flutter,就等于掌握了一把开启多平台应用开发大门的钥匙。无论是初出茅庐的新手,还是经验丰富的开发老将,Flutter 都能为其职业生涯增添璀璨光芒,带来更多的发展机遇和可能。
二、学习前的准备工作
在开启 Flutter 的学习之旅前,我们得先准备好 “武器”,也就是相关的软件工具。
Dart SDK:Dart 是 Flutter 的开发语言,就像是厨师手中的菜刀,是不可或缺的工具。你可以前往 Dart 官网(https://dart.dev/get-dart )下载适合你操作系统的安装包。下载完成后,按照安装向导的提示进行傻瓜式安装即可。安装完成后,还需要配置环境变量,将 Dart SDK 的 bin 目录路径添加到系统的 Path 变量中。比如在 Windows 系统中,假设你将 Dart SDK 安装在 C:\dart-sdk 目录下,那就把 C:\dart-sdk\bin 添加到 Path 变量里。配置好后,打开命令行窗口,输入 dart --version,如果能正确显示 Dart 的版本号,那就说明安装和配置成功啦。
Flutter SDK:这是 Flutter 开发的核心工具包,如同建筑工人的建筑材料。获取 Flutter SDK 有两种常见方式,一是直接从 Flutter 官网(https://flutter.cn/docs/get-started/install )下载 zip 包,然后解压到你喜欢的目录;二是使用 git 命令进行下载,在命令行中执行 git clone -b stable https://github.com/flutter/flutter.git ,它会将 Flutter SDK 下载到当前目录下。下载完成后,同样要配置环境变量,将 Flutter SDK 的 bin 目录路径添加到系统的 Path 变量中。接着,在命令行中执行 flutter doctor 命令,它就像一个医生,会检查你的开发环境是否存在问题,并给出相应的提示和建议,按照提示进行处理,直到所有检查项都通过。
集成开发环境(IDE):这里强烈推荐使用 Android Studio 或 Visual Studio Code,它们就像是一个超级工作台,为我们提供了丰富的功能和便捷的开发体验。以 Android Studio 为例,在安装完成后,还需要安装 Flutter 和 Dart 插件。打开 Android Studio,点击菜单栏中的 File -> Settings(Windows/Linux)或 Android Studio -> Preferences(Mac),在弹出的窗口中选择 Plugins,然后在搜索框中分别输入 Flutter 和 Dart,点击安装按钮进行安装。安装完成后,重启 Android Studio,插件就会生效。
三、Dart 语言基础入门
Dart 语言作为 Flutter 开发的基石,其重要性不言而喻。它就像是大厦的地基,只有地基打得牢固,才能构建出雄伟壮观的应用大厦。掌握 Dart 语言,是深入学习 Flutter 的必经之路。下面,我们就来深入了解 Dart 语言的基本语法、数据类型、控制流等核心知识。
3.1 基本语法
Dart 语言的基本语法简洁而强大,它融合了多种编程语言的优点,易于学习和掌握。在 Dart 中,变量的声明和使用非常灵活,你既可以显式指定变量的类型,如int age = 20;,也可以使用var关键字让 Dart 自动推断变量类型,例如var name = "Alice";。需要注意的是,一旦变量被赋值,其类型就会被确定,后续不能再赋予不同类型的值,这体现了 Dart 语言的强类型特性。
3.2 数据类型
Dart 语言提供了丰富的数据类型,以满足不同的编程需求。基本数据类型包括整型(int)、浮点型(double)、布尔型(bool)和字符串(String) 。整型用于表示整数,如int num = 10;;浮点型用于表示带有小数部分的数字,例如double pi = 3.14159;;布尔型只有两个值:true和false,常用于条件判断,比如bool isSuccess = true;;字符串则用于存储文本信息,使用单引号或双引号包裹,例如String message = "Hello, Dart!";。
除了基本数据类型,Dart 还支持复合数据类型,如列表(List)、映射(Map)和集合(Set)。列表是一种有序的元素集合,允许重复元素,例如List<int> numbers = [1, 2, 3, 4, 5];;映射是键值对的集合,每个键对应一个唯一的值,例如Map<String, int> ages = {"Alice": 20, "Bob": 25};;集合是不包含重复元素的无序集合,例如Set<String> names = {"Alice", "Bob", "Charlie"};。这些复合数据类型为开发者提供了强大的数据组织和管理能力。
3.3 控制流
控制流语句是编程语言的重要组成部分,它允许程序根据不同的条件执行不同的代码块,实现复杂的逻辑功能。Dart 语言提供了多种控制流语句,包括条件语句(if - else、switch - case)和循环语句(for、while、do - while)。
if - else 语句用于根据条件判断执行不同的代码块。例如:
int score = 85;
if (score >= 90) {
print("优秀");
} else if (score >= 60) {
print("及格");
} else {
print("不及格");
}
switch - case 语句则用于根据不同的值执行不同的代码块,使代码更加简洁和易读。例如:
int day = 3;
switch (day) {
case 1:
print("星期一");
break;
case 2:
print("星期二");
break;
case 3:
print("星期三");
break;
default:
print("其他");
}
for 循环常用于重复执行一段代码特定次数。例如:
for (int i = 0; i < 5; i++) {
print(i);
}
while 循环和 do - while 循环则根据条件的真假来决定是否继续循环。while 循环先判断条件,再执行循环体;do - while 循环则先执行一次循环体,再判断条件。例如:
int i = 0;
while (i < 5) {
print(i);
i++;
}
int j = 0;
do {
print(j);
j++;
} while (j < 5);
通过灵活运用这些控制流语句,开发者可以实现各种复杂的业务逻辑,让程序按照预期的方式运行。
四、Flutter 核心概念剖析
当我们深入 Flutter 的世界,就会遇到几个核心概念,它们如同游戏中的关键道具,掌握了它们,就能在开发中如鱼得水。
4.1 Widget
Widget 堪称 Flutter 的基石,是构建用户界面的基本单元。你可以把它想象成乐高积木,每一块都有独特的形状和功能,通过组合不同的积木,就能搭建出各种各样的建筑。在 Flutter 里,无论是简单的文本、按钮,还是复杂的布局、列表,都是一个个 Widget。
Widget 分为两类:无状态的StatelessWidget和有状态的StatefulWidget。StatelessWidget就像一个固定的雕塑,一旦创建,其属性和外观就不会改变。例如,显示应用名称的文本标签,它的内容和样式在应用运行期间始终保持不变,就适合用StatelessWidget来实现。以下是一个简单的StatelessWidget示例:
import 'package:flutter/material.dart';
class MyStatelessWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('这是一个无状态Widget');
}
}
在这个例子中,MyStatelessWidget继承自StatelessWidget,并实现了build方法,返回一个显示固定文本的Text组件。
而StatefulWidget则像一个智能机器人,能够根据不同的情况改变自己的状态和外观。比如一个计数器组件,当用户点击按钮时,计数值会增加,界面也会随之更新,这就需要StatefulWidget来实现。它有一个与之对应的State类,用于存储和管理状态。下面是一个计数器的StatefulWidget示例:
import 'package:flutter/material.dart';
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _count = 0;
void _incrementCounter() {
setState(() {
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('计数: $_count'),
RaisedButton(
child: Text('增加'),
onPressed: _incrementCounter,
),
],
);
}
}
在这个示例中,CounterWidget继承自StatefulWidget,_CounterWidgetState类负责管理状态。_count变量存储计数值,_incrementCounter方法通过调用setState方法来更新状态,从而触发界面的重新构建,实现计数功能。
4.2 State
State 与StatefulWidget紧密相连,是存储和管理StatefulWidget可变状态的关键。它就像是一个容器,保存着 Widget 在运行时需要改变的数据。比如上面计数器示例中的_count变量,就存储在State中。
State 具有生命周期方法,这些方法就像是人生的不同阶段,每个阶段都有特定的任务。initState方法在 State 对象被创建时调用,通常用于初始化一些数据或资源;didUpdateWidget方法在 Widget 的属性发生变化时被调用;dispose方法则在 State 对象被销毁时调用,用于释放资源,比如取消订阅、关闭流等。合理利用这些生命周期方法,能够让我们的应用更加健壮和高效。
4.3 BuildContext
BuildContext 可以理解为 Widget 在 Widget 树中的 “位置标签”,它包含了对 Widget 树中其他 Widget 的引用,就像一个导航地图,帮助我们在 Widget 树中查找和访问其他 Widget。通过 BuildContext,我们可以获取父 Widget 的属性或方法,访问主题数据、进行导航等操作。
例如,在一个页面中,我们想要获取当前的主题颜色来设置文本颜色,就可以通过Theme.of(context).primaryColor来实现,这里的context就是 BuildContext。又比如,我们要在点击按钮时打开一个新的页面,就可以使用Navigator.of(context).push方法,context在这里起到了定位和导航的作用。
五、搭建第一个 Flutter 应用
现在,我们已经摩拳擦掌,迫不及待地想要搭建第一个 Flutter 应用了。就像搭建一座小房子,我们一步步来。
5.1 创建 Flutter 项目
打开你喜爱的 IDE,这里以 Android Studio 为例。点击菜单栏中的 File -> New -> New Flutter Project,在弹出的窗口中,选择 Flutter Application,然后点击 Next。接下来,填写项目名称、描述、存放路径等信息,就像给房子取名字、写介绍、选地址一样。填写完成后,点击 Finish,稍等片刻,一个崭新的 Flutter 项目就创建成功啦!
5.2 分析默认代码结构和功能
项目创建好后,我们来看看它的 “内部构造”。打开 lib 目录下的 main.dart 文件,这是整个应用的 “心脏”,所有的代码逻辑从这里开始。
import 'package:flutter/material.dart';
void main() => runApp(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'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
首先,import 'package:flutter/material.dart';这行代码导入了 Flutter 的 Material Design 库,它就像一个装满各种精美建筑材料的仓库,为我们提供了丰富的 UI 组件和样式。
void main() => runApp(MyApp());是应用的入口,就像房子的大门,程序从这里开始执行,runApp方法会启动并运行我们的应用,参数MyApp()是应用的根组件。
MyApp类继承自StatelessWidget,它定义了应用的整体结构和主题。MaterialApp是一个重要的组件,它为应用提供了 Material Design 风格的基础架构,包括导航栏、主题颜色等。title属性设置应用的标题,theme属性定义应用的主题,home属性指定应用的主页为MyHomePage。
MyHomePage类继承自StatefulWidget,表示这是一个有状态的页面。_MyHomePageState类则负责管理MyHomePage的状态。_counter变量用于记录按钮的点击次数,_incrementCounter方法是按钮的点击事件处理函数,通过setState方法更新_counter的值,从而触发界面的重新构建,实现计数功能。
Scaffold是一个 Material Design 风格的布局组件,它包含了appBar(顶部导航栏)、body(主体内容区域)和floatingActionButton(浮动操作按钮)等属性。appBar中的title显示页面标题,body中通过Column组件以垂直布局的方式展示了两个Text组件,分别显示提示文本和计数值,floatingActionButton点击后会调用_incrementCounter方法。
5.3 运行测试