工程結構
開啟Android studio 建立一個flutter 專案,會預設建立一個計數器專案。在右邊project 下,可以看到:
分析一下幾個重要的檔案目錄和檔案:
android:包含Android的特定檔案和Android子工程
build:Android 和iOS 的構建產物
ios:包含iOS 的特定檔案和iOS 子工程
lib:放置flutter 程式碼
main.dart:程式的入口檔案,類似Android 的application
test:測試檔案
flutter_app.iml:工程配置檔案
pubspec.lock:記錄當前專案實際依賴資訊的檔案
pubspec.yaml:管理第三方庫和資原始檔
複製程式碼
之所以有Android 和iOS 子專案,是因為flutter 最終會以原生的形式執行。
從簡單的demo學習flutter專案的執行機制
在flutter 的世界中,一切都是widget,widget 是元件視覺效果的封裝,是 UI 介面的載體,通過 build方法來構建UI頁面。 看看main.dart 檔案中的程式碼
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
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),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
複製程式碼
- 從main函式開始,呼叫
runApp
方法 傳入MyApp(就是一個widget),APP就是我們看到的首頁。 - 在 MyApp的build 方法中,返回了 MaterialApp(也是一個widget),裡面還有很多可配置的屬性,比如應用主題、應用名稱、語言識別符號、元件路由等。
- 在 MaterialApp,看到 MyHomePage(也是一個widget),但是這個 StatefulWidget 的子類,構建UI不是直接通過build 方法,而是交給 _MyHomePageState來完成。
到這來就可以看到,在flutter 中有兩種 widget,StatelessWidget 和 StatefulWidget。
StatelessWidget:無狀態的widget,UI構建的從一開始就是確定的,在 widget 的生命週期中不會發生變化。
StatefulWidget:有狀態的widget,在widget 的生命週期中資料發生變化,在資料發生變化後,呼叫 setState方法來通知flutter 框架,重新建立widget。
隨著資料的變化重新建立和銷燬widget,會不會對效能有影響呢,flutter 如何優化的?
答案是:不會。因為框架內部會通過一箇中間層去收斂上層 UI 配置對底層真實渲染的改動,從而最大程度降低對真實渲染檢視的修改,提高渲染效率,而不是上層 UI 配置變了就需要銷燬整個渲染檢視樹重建。
總結
從上面可以看出,在flutter 的世界裡,widget 是無處不在,在頁面上看到的一切的一切都是widget,如:AppBar、Center、Text、FloatingActionButton……都是widget,我們可以在widget構建的時候,做好配置,如,Text 文字大小、文字顏色、文字內容、點選事件等等,然後在資料發生變化後,通過呼叫 setState
方法,就可以更新UI了。