老孟导读:这是老孟翻译的精品文章,此篇文章共有 3.6K的赞。
几年前,我使用Java和Objective-C涉足了Android和iOS开发,使用它们尝试了大约1个月后,我决定继续前进。
但是最近,我了解了Flutter,并决定再次开发移动应用程序。我立即爱上了它,因为它使开发多平台应用程序变得非常有趣。自了解以来,我已经创建了一个应用程序和一个使用它的库。 Flutter似乎是向前迈出的非常有希望的一步,我想解释一些我为什么会相信的不同原因。
由Dart提供支持
Flutter使用Google开发的Dart语言。如果您以前使用过Java,那么您将非常熟悉Dart的语法,因为它们非常相似。除了语法外,Dart是一种完全不同的语言。
我不会深入讨论Dart,因为它有点超出范围,但我想讨论一下我认为最有用的功能之一。此功能支持异步操作。 Dart不仅支持它,而且使其异常容易。
如果您要执行IO或其他耗时的操作(例如查询数据库),那么很可能会在所有Flutter应用程序中使用此功能。没有异步操作,任何耗时的操作都会导致程序冻结直到完成。为防止这种情况,Dart为我们提供了async 和 await 关键字,这些关键字使我们的程序可以在等待这些较长的操作完成时继续执行。
让我们看几个例子:一个没有异步操作,一个有异步操作。
// Without asynchronous operations
import 'dart:async';
main() {
longOperation();
printSomething();
}
longOperation() {
Duration delay = Duration(seconds: 3);
Future.delayed(delay);
print('Waited 3 seconds to print this and blocked execution.');
}
printSomething() {
print('That sure took a while!');
}
输出t:
Waited 3 seconds to print this and blocked execution.
That sure took a while!
这不理想。没有人愿意使用在执行长时间操作时冻结的应用程序。因此,让我们对其进行一些修改,并使用 async 和 await 关键字。
// With asynchronous operations
import 'dart:async';
main() {
longOperation();
printSomething();
}
Future<void> longOperation() async {
var retVal = await runLongOperation();
print(retVal);
}
const retString = 'Waited 3 seconds to return this without blocking execution.';
Duration delay = Duration(seconds: 3);
Future<String> runLongOperation() => Future.delayed(delay, () => retString);
printSomething() {
print('I printed right away!');
}
再次输出:
I printed right away!
Waited 3 seconds to return this without blocking execution.
多亏了异步操作,我们能够执行需要一段时间才能完成的代码,而不会阻止其余代码的执行。
编写一次,在Android和iOS上运行
考虑到您需要为Android和iOS使用不同的代码库,开发移动应用程序可能会花费很多时间。除非您使用Flutter之类的SDK,否则您只有一个代码库可让您为两个操作系统构建应用程序。不仅如此,您还可以在本地完全运行它们。这就意味着诸如滚动和导航之类的功能,就像它们对于所使用的操作系统一样。
为了保持简单性这一主题,只要您运行的是设备或模拟器,Flutter都可以使创建和运行应用程序的过程像单击按钮一样简单。
UI开发
UI开发是我几乎从未期待过的事情之一。我更多地是后端开发人员,因此,在处理高度依赖它的东西时,我需要一些简单的东西。这是Flutter在我眼中闪耀的地方。
通过将不同的小部件组合在一起并对其进行修改以适合您的应用程序外观来创建UI。您几乎完全可以控制这些小部件的显示方式,因此始终可以得到所需的确切信息。为了布置UI,您需要使用小部件,例如行,列和容器。对于内容,您具有诸如Text和RaisedButton之类的小部件。这只是Flutter提供的小部件中的几个,还有更多。使用这些小部件,我们可以构建一个非常简单的UI:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter App'),
centerTitle: true,
elevation: 0,
),
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: Text('Some text'),
),
Container(
child: RaisedButton(
onPressed: () {
// Do something on press
},
child: Text('PRESS ME'),
),
),
],
),
],
),
);
}
Flutter可轻松设置主题主题。您可以手动更改字体,颜色,然后逐一查找所有内容,但这花费的时间太长。相反,Flutter为我们提供了一个名为ThemeData的东西,它允许我们设置颜色,字体,输入字段等的值。此功能非常适合使您的应用程序外观保持一致。
theme: ThemeData(
brightness: Brightness.dark,
canvasColor: Colors.grey[900],
primarySwatch: Colors.teal,
primaryColor: Colors.teal[500],
fontFamily: 'Helvetica',
primaryTextTheme: Typography.whiteCupertino.copyWith(
display4: TextStyle(
color: Colors.white,
fontSize: 36,
),
),
),
通过此ThemeData,我们可以设置应用程序的颜色,字体系列和某些文本样式。除文本样式外,所有内容都会自动在整个应用范围内应用。必须为每个文本小部件手动设置文本样式,但这仍然很简单:
child: Text(
'Some text',
style: Theme.of(context).primaryTextTheme.display4,
),
为了提高效率,Flutter可以热重载应用程序,因此您无需在每次更改UI时都重新启动它。现在,您可以进行更改,将其保存,然后在一秒钟左右的时间内看到更改。
库
Flutter开箱即用地提供了许多很棒的功能,但是有时候您需要的东西比它所提供的更多。考虑到Dart和Flutter可用的大量库,这根本就不是问题。有兴趣在您的应用中投放广告吗?有一个库。需要新的小部件吗?有库。
如果您更喜欢自己动手做,请创建自己的库并立即与社区其他成员共享。将库添加到您的项目很简单,可以通过在pubspec.yaml文件中添加一行来完成。例如,如果要添加sqflite库:
dependencies:
flutter:
sdk: flutter
sqflite: ^1.0.0
将其添加到文件中后,运行flutter软件包get,您就可以开始了。库使开发Flutter应用程序变得轻而易举,并在开发过程中节省了大量时间。
后端开发
如今,大多数应用程序都依赖某种数据,这些数据需要存储在某个地方,以便以后显示和使用。因此,在使用新的SDK(例如Flutter)创建应用程序时,请记住这一点,这一点很重要。
再说一次,Flutter应用程序是使用Dart制作的,对于后端开发,Dart很棒。在本文中,我已经谈到了许多简单性,并且使用Dart和Flutter进行后端开发也不例外。对于初学者和专家而言,创建数据驱动的应用程序极其简单,但是这种简单性绝不等于缺乏质量。
要将其与上一节联系起来,可以使用库,因此您可以使用自己选择的数据库。使用sqflite库,我们可以相当快地启动并运行SQLite数据库。而且由于有了单例,我们几乎可以在任何地方访问数据库并查询它,而无需每次都重新创建对象。
class DBProvider {
// Singleton
DBProvider._();
// Static object to provide us access from practically anywhere
static final DBProvider db = DBProvider._();
Database _database;
Future<Database> get database async {
if (_database != null) {
return _database;
}
_database = await initDB();
return _database;
}
initDB() async {
// Retrieve your app's directory, then create a path to a database for your app.
Directory documentsDir = await getApplicationDocumentsDirectory();
String path = join(documentsDir.path, 'money_clip.db');
return await openDatabase(path, version: 1, onOpen: (db) async {
// Do something when the database is opened
}, onCreate: (Database db, int version) async {
// Do something, such as creating tables, when the database is first created.
// If the database already exists, this will not be called.
}
}
}
从数据库检索数据后,可以使用模型将其转换为对象。或者,如果要将对象存储在数据库中,则可以使用相同的模型将其转换为JSON。
class User {
int id;
String name;
User({
this.id,
this.name,
});
factory User.fromJson(Map<String, dynamic> json) => new User(
id: json['id'],
name: json['name'],
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
};
}
如果没有向用户显示的数据,这些数据并没有那么有用。这是Flutter附带诸如FutureBuilder或StreamBuilder之类的小部件的地方。如果您想更深入地了解如何使用Flutter,SQLite和其他技术来创建数据驱动的应用程序,建议您阅读我写的文章:
最后的想法
使用Flutter,可能性几乎是无限的,因此甚至可以轻松创建超级扩展的应用程序。如果您开发移动应用程序并且还没有尝试Flutter,我强烈建议您这样做,因为我相信您也会爱上它。在使用Flutter几个月后,我认为可以肯定地说这是移动开发的未来。如果没有,那肯定是朝正确方向迈出的一步。
交流
老孟Flutter博客地址(330个控件用法):http://laomengit.com