老孟導讀:這是老孟翻譯的精品文章,此篇文章共有 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個控制元件用法):laomengit.com
歡迎加入Flutter交流群(微信:laomengit)、關注公眾號【老孟Flutter】: