一、利用IDE高效組合Widget
在Flutter中,UI的構建是通過Widget的層層巢狀實現的,開發過程中不可避免地需要頻繁修改Widget樹,從中插入或者移除一些Widget。
除了手動寫程式碼和剪下貼上去修改Widget樹之外,在Android Studio和Visual Studio Code中,你還有更高效的方法可以使用:
- 在Android Studio中
- 在Visual Studio Code中
二、理解下劃線開頭命名的含義
Flutter所使用的Dart語言,沒有類似Java的publice protect private,以_開頭的變數、函式和類,意味著它僅在庫中是可視的
Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore (_) are visible only inside the library.出處
觀察以下幾個例子,加深理解:
-
變數
name變數以_開頭後,雖然都是繼承於Fruit,但是由於Apple不在同一庫中,因此它無法訪問父類的name屬性。
-
函式
getName方法以_開頭後,雖然都是繼承於Fruit,但是由於Apple不在同一庫中,因此它無法訪問父類的getName方法,也無須實現它。
-
類
Banana類可以訪問在同一個庫中的_Fruit類,但是由於Apple不在同一庫中,因此它無法訪問_Fruit類。
三、區別final與const
在Dart中,當你不需要去改變一個變數的時候,應該使用final或者const,而不是使用var去宣告一個變數。
一個final變數只允許被賦值一次,必須在定義時或者建構函式參數列中將其初始化。
const所修飾的是編譯時常量,我們在編譯時就已經知道了它的值,它的值是不可改變的。
它們的區別就在於,const比final更加嚴格,看以下幾個例子:
final List<String> list = [];
list.add('1'); // 正確
const List<String> list = [];
list.add('1'); // 錯誤,執行時報錯:Cannot add to an unmodifiable list
複製程式碼
final timestamp = new DateTime.now().millisecondsSinceEpoch; // 正確
const timestamp = new DateTime.now().millisecondsSinceEpoch;
// 錯誤,編譯前報錯:Const variables must be initialized with a constant value
複製程式碼
四、使用Debug Painting除錯介面
Flutter提供的Debug Painting可以很方便地協助我們觀察介面的佈局,除錯介面的開發
在Android Studio和Visual Studio Code中都有提供開關去顯示或隱藏Debug Painting(前提是App處於除錯執行狀態):- 在Android Studio中
- 在Visual Studio Code中
五、使用FocusScope轉移焦點,隱藏輸入法
我們在開發App的時候,會經常遇到當點選空白區域時將輸入法隱藏的需求。一想到輸入法,大家可能都會想通過Method Channle,讓原生實現隱藏輸入法的辦法來解決。其實我們可以通過FocusScope來轉移焦點,同樣能夠達到隱藏輸入法的目的。
Container(
height: 500.0,
child: new GestureDetector(
onTap: () {
// 通過GestureDetector捕獲點選事件,再通過FocusScope將焦點轉移至空焦點——new FocusNode()
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
margin: EdgeInsets.all(30.0),
child: ListView(children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Username'),
),
TextField(
decoration: InputDecoration(labelText: 'Password'),
)
])),
),
),
複製程式碼
開發過程中還發現了Flutter一個bug,這裡傳遞給FocusScope的context不能在MaterialApp下面,即你需要將這部分程式碼放到獨立的一個Widget裡面。 具體參考這個issue最後一個評論。