1. 概述
什么是Flutter
Flutter 是一个开源的移动应用开发框架,由 Google 开发,旨在帮助开发者构建高性能、高品质的跨平台移动应用。Flutter 提供了丰富的组件、工具和库,使开发者能够以一套代码基础构建适用于 iOS、Android、Web 和桌面平台的应用程序。
###Flutter框架的优点:
-
快速开发:Flutter 提供了热重载功能,允许开发者在应用程序运行时即时查看代码更改的效果,大大加速了开发周期。
-
灵活性:Flutter 的组件灵活性极高,允许开发者根据需要自定义和组合组件,以满足不同的设计需求。
-
高性能:Flutter 使用自绘引擎,能够实现高性能的渲染效果,并在各种平台上保持一致的性能表现。
-
跨平台:Flutter 具有真正的跨平台能力,开发者可以使用相同的代码库构建多个平台上的应用程序,从而降低了开发和维护成本。
-
接近原生性能:Flutter 不是通过 WebView 或 JavaScript 来渲染 UI,而是使用平台的原生控件进行渲染,因此具有接近原生应用程序的性能和体验。
Flutter框架的不足:
-
生态没有原生Android或者IOS那么完善,有些需要的插件或者三方库缺失。
-
性能没有原生丝滑,但已经接近原生体验,移动应用跨平台框架远胜于React Native
2. 开发环境和工具
配置环境:
在masOS下可以同时进行Android和iOS设备的测试。Windows电脑上不能运行调试ios设备。 具体配置可以见 book.flutterchina.club/chapter1/in…
开发IDE:
Android Studio、XCode、VSCode等。
可调试的手机设备:
Android 模拟器(依赖AndroidStudio提供的工具 ) IOS模拟器(依赖XCode提供的工具) Android手机(需要打开开发者权限,部分手机不一定能成功USB连接调试) IOS手机(IOS版本高似乎都不支持真机调试,即便能运行,在launch的时候也会退出)
开发语言
Dart 是一种由谷歌开发的面向对象、静态类型、可选的即时编译语言。它最初于2011年发布,旨在成为 Web、移动应用和服务器端等各种平台的通用编程语言。语法和主流的Java、Python、等待语言大体类似,以下是 Dart 语言的一些关键特点和概述:
-
面向对象:Dart 是一种纯粹的面向对象编程语言,所有的值都是对象,而且支持类、继承、多态和抽象类等面向对象的特性。
-
静态类型:Dart 是一种静态类型语言,但也支持类型推断。通过类型检查,可以在编译时捕获许多错误,从而提高代码的稳定性和可维护性。
-
异步编程:Dart 内置了强大的异步编程支持,通过 async 和 await 关键字,开发者可以轻松地编写异步代码,处理事件和异步操作。
-
库和包管理:Dart 提供了丰富的标准库和包管理工具(如 pub),可以轻松地引入和管理依赖库,提高了代码复用性和开发效率。
-
跨平台:Dart 旨在成为一个通用的编程语言,可以在多种平台上运行,包括 Web、移动应用和服务器端。通过 Flutter 框架,可以使用 Dart 构建高性能、美观的移动应用。
Dart代码示例:
下面代码的示例,是app登录时调用接口的示例: 代码处理的逻辑依次是: 请求登录接口 -> 设置Token -> 处理消息推送 -> 请求app的菜单权限 -> 设置app需要用到的一些个人账户信息,存储在本地 -> 如果是第一次登录,需要重置密码 -> 请求按钮权限 -> 去到app首页
Service.pwdLogin(username: username, password: password)
.then((value) async {
if (value == null) return;
//需要token请求修改密码接口,所以放在前面
await setToken(value["accessToken"]);
try {
try {
unawaited(SharedPreferenceService.instance
.get(getuiClientId, '')
.then(
(cid) => MessageAsk.bindPush(cid, Get.locale!.languageCode)));
} catch (e) {
LogUtil.log('登陆绑定推送失败不处理');
}
//请求权限
bool? menuRes = await BtnPermissionManager().loadMenuList();
if (menuRes != true) {
HYXLoading.showToast(LocaleKeys.loginFail.tr);
await SharedPreferenceService.instance.remove(keyLoginToken);
return;
}
} catch (e) {
HYXLoading.showToast(LocaleKeys.loginFail.tr);
await SharedPreferenceService.instance.remove(keyLoginToken);
return;
}
//设置isOwner
if (value["role"] != null && value["role"]["isOwner"] != null) {
await setIsOwner(value["role"]["isOwner"]!.toString());
}
//判断是否是体验账号
if (value["role"] != null && value["role"]["isExperience"] != null) {
setIsExperience(value["role"]["isExperience"].toString());
if (value["role"]["isExperience"].toString() == "0") {
await setAccount(username);
}
}
//设置isBSOwner
if (value["role"] != null && value["role"]["isBSOwner"] != null) {
var bsOwner = value["role"]["isBSOwner"]!;
_isBSOwner = bsOwner == 1;
await setIsBSOwner(bsOwner);
}
// 1 第一次登陆 0:不是第一次登陆
if (value["loginFirst"]?.toString() == "1") {
//要去重置密码
HYXLoading.showToast(LocaleKeys.loginSucceededResetPasswordFirst.tr);
await HYXRoutePushUtil.pushName(RouteManager.registerSetPwd,
arguments: SetPwdParamModel(systemPwd: password));
} else {
await _setLoginState(true);
unawaited(HYXRoutePushUtil.changeRootPage());
}
unawaited(Provider.of<BtnPermissionProvider>(
AppShare.instance.rootContext,
listen: false)
.loadAllButtonsPermission());
});
Dart语言值得注意的地方
(1)空安全性:
Dart 2.12 版本引入了空安全性,使得变量可以明确指定是否可以为空。因此,在编写 Dart 代码时,应该注意对于可能为空的变量进行合适的处理,以避免空指针异常。
String name = 'Alice';
String? email;
print('Name: $name');
if (email != null) {
print('Email: $email');
} else {
print('Email is not provided.');
}
(2)支持异步编程:
Dart 提供了强大的异步编程支持,包括 async 和 await 关键字、Future 类型等,使开发者能够轻松处理异步操作,编写高效的异步代码。
Future<String> fetchUserData() async {
// 模拟异步操作,比如从网络获取数据
await Future.delayed(Duration(seconds: 2));
return 'Name: Alice, Email: alice@example.com';
}
(3)单线程语言:
Dart 作为一个单线程语言,虽然提供了多线程的机制,但是在多线程的资源是隔离的,两个线程之间资源是不互通的。
Dart 的多线程数据交互需要从 A 线程传给 B 线程,再由 B 线程返回给 A 线程。而像 Android 在主线程开一个子线程,子线程可以直接拿主线程的数据,而不用让主线程传给子线程。
由于 Dart 是单线程语言,因此在执行代码时不会出现多线程竞争资源的情况,这样可以避免许多常见的多线程问题,如死锁、竞态条件等。
为了解决长时间运行操作导致 UI 阻塞的问题,Dart 提供了异步编程特性,如 Future、async 和 await,允许开发者在主线程中发起异步操作,然后在操作完成时得到通知并处理结果,而不会阻塞主线程的执行。
总的来说,Dart 的单线程模型通过事件循环和异步编程特性,提供了一种简单而有效的方式来处理并发和异步操作,同时避免了多线程编程中常见的问题。
3.使用Flutter编写一个简单页面:计数器示例
截图:
代码示例
import 'package:flutter/material.dart';
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, required 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),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
4.使用Flutter进行移动应用管理
###(1)状态管理 Flutter 状态管理是指在 Flutter 应用中有效地管理应用的数据和状态,以确保用户界面(UI)与数据之间的一致性和交互性。在复杂的应用中,数据通常会在不同的部分之间流动和变化,而状态管理的目标是帮助开发者更好地组织、更新和共享这些数据。
状态管理作用
- 数据共享和同步:在应用程序中,不同部分可能需要共享和同步数据。通过状态管理,可以轻松地在应用程序的各个部分之间共享数据,并确保数据的一致性。
- UI更新:Flutter状态管理可以帮助开发者管理应用程序中的UI状态,以便在数据变化时更新用户界面。这样可以确保应用程序的UI与数据的状态保持同步。
- 复杂状态管理:随着应用程序变得越来越复杂,管理应用程序的状态变得更加困难。Flutter状态管理工具可以帮助开发者更有效地管理应用程序的状态,使代码更具可维护性和可扩展性。
- 性能优化:有效的状态管理可以帮助应用程序避免不必要的重绘和重新构建,从而提高应用程序的性能和响应速度。
- 代码结构:通过良好的状态管理,开发者可以更好地组织应用程序的代码结构,使其更易于理解和维护。
下面是使用比较多的状态管理方法及优缺点:
1. Provider
轻量级、易学习、内置于Flutter中,适用于基本状态管理。 pub.dev/packages/pr…
在使用Provider的时候,我们主要关心三个概念: ChangeNotifier:真正数据(状态)存放的地方 ChangeNotifierProvider:Widget树中提供数据(状态)的地方,会在其中创建对应的ChangeNotifier Consumer:Widget树中需要使用数据(状态)的地方
2. flutter_bloc
基于块模式构建,将业务逻辑与用户界面解耦,适用于复杂的状态管理。 pub.dev/packages/fl…
3. Get
简单易用:
GetX提供了简洁而直观的API,使得状态管理和导航等功能变得非常容易实现。 开发者可以通过少量的代码实现复杂的功能,提高开发效率。
性能优秀:
GetX被设计为高性能的状态管理库,具有出色的性能表现。 GetX使用响应式编程和观察者模式,可以确保只有在数据变化时才会触发UI更新,从而提高应用程序的性能。
路由管理:
GetX提供了强大的路由管理功能,支持命名路由、动画过渡等。 开发者可以轻松地管理应用程序的导航逻辑,实现页面之间的切换和传递参数。
轻量级:
GetX是一个轻量级的库,不会给应用程序增加过多的负担。 使用GetX可以避免引入过多的依赖,使应用程序保持简洁和高效。
###(2)路由管理 简单来说,路由管理就是页面之间如何调整、传递参数等一系列操作。
- GetX,get提供了一套路由管理
- 系统自带的Navigator
- 其他三方插件提供的路由管理。
###(3)数据持久化管理 app本地也是可以存储数据的,有以下几种数据存储类型:
Shared Preferences:
这是一种轻量级的键值对存储方案,用于存储小量的简单数据,例如用户偏好设置、应用程序配置等。Shared Preferences 使用异步 API 进行读写操作,可以在整个应用程序中共享数据。
文件存储:
你可以将数据存储在文件中,这对于存储结构化数据或大量数据很有用。Flutter 提供了文件操作的 API,包括读取、写入、删除和查询文件等操作。你可以使用 JSON、CSV、SQLite 等格式来组织和存储数据。
SQLite 数据库:
如果你需要在 Flutter 中使用关系型数据库,可以使用 SQLite。Flutter 提供了 sqflite 插件,它是 SQLite 数据库的 Flutter 封装。你可以使用 sqflite 插件执行 SQL 查询、插入、更新和删除操作,以及管理数据库表结构。
Hive 数据库:
Hive 是一个轻量级的、快速的、键值型的数据库,适用于在 Flutter 中存储结构化数据。Hive 使用自定义的二进制格式来存储数据,因此比 SQLite 更快。它还提供了方便的查询和过滤功能。
5.常用的三方库
加载网络图片同时进行缓存
cached_network_image 3.3.1 pub.dev/packages/ca…
加载h5页面
webview_flutter: ^4.7.0 pub.dev/packages/we…
语言国际化
intl: ^0.19.0 pub.dev/packages/in… 或者:Get
获取手机定位
geolocator: ^11.0.0 pub.dev/packages/ge…