老孟導讀:這是老孟翻譯的精品文章,此篇文章共有 3.6K的贊。加入老孟Flutter交流羣(wx:laomengit),精彩文章不容錯誤。
幾年前,我使用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中使用Streams,BLoC和SQLite
最後的想法
使用Flutter,可能性幾乎是無限的,因此甚至可以輕鬆創建超級擴展的應用程序。如果您開發移動應用程序並且還沒有嘗試Flutter,我強烈建議您這樣做,因爲我相信您也會愛上它。在使用Flutter幾個月後,我認爲可以肯定地說這是移動開發的未來。如果沒有,那肯定是朝正確方向邁出的一步。
交流
老孟Flutter博客地址(330個控件用法):http://laomengit.com
歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】: