在Flutter中,UI的構建是經過Widget的層層嵌套實現的,開發過程當中不可避免地須要頻繁修改Widget樹,從中插入或者移除一些Widget。git
除了手動寫代碼和剪切粘貼去修改Widget樹以外,在Android Studio和Visual Studio Code中,你還有更高效的方法可使用:github
Flutter所使用的Dart語言,沒有相似Java的publice protect private,以_開頭的變量、函數和類,意味着它僅在庫中是可視的bash
Libraries not only provide APIs, but are a unit of privacy: identifiers that start with an underscore (_) are visible only inside the library.出處ide
觀察如下幾個例子,加深理解:函數
name變量以_開頭後,雖然都是繼承於Fruit,可是因爲Apple不在同一庫中,所以它沒法訪問父類的name屬性。 ![]()
getName方法以_開頭後,雖然都是繼承於Fruit,可是因爲Apple不在同一庫中,所以它沒法訪問父類的getName方法,也無須實現它。 ![]()
Banana類能夠訪問在同一個庫中的_Fruit類,可是因爲Apple不在同一庫中,所以它沒法訪問_Fruit類。 ![]()
在Dart中,當你不須要去改變一個變量的時候,應該使用final或者const,而不是使用var去聲明一個變量。佈局
一個final變量只容許被賦值一次,必須在定義時或者構造函數參數表中將其初始化。ui
const所修飾的是編譯時常量,咱們在編譯時就已經知道了它的值,它的值是不可改變的。spa
它們的區別就在於,const比final更加嚴格,看如下幾個例子:3d
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
複製代碼
官方文檔調試
Flutter提供的Debug Painting能夠很方便地協助咱們觀察界面的佈局,調試界面的開發
咱們在開發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最後一個評論。