Statelesswidget
如果一個Widget從初始化到使用再到銷燬,整個過程中都不需要修改其UI的樣式,例如純展示頁面,我們就用Statelesswidget。常見的Statelesswidget有:Text、Icon、ImageIcon、Dialog等。可以看到這些往往都是一些展示類的,不需要改變其狀態的控件。
使用Statelesswidget更輕量,更節省內存資源。初始化Statelesswidget的時候不會附帶一些動態更新UI的方法,這樣也會提升我們軟件的性能。
需要注意的是:
在iOS開發中,初始化一個Label並命名為la,改變它的文字內容,會調用la.text = @"new text",我們可以理解為Label不是Statelesswidget的,因為它的text屬性被改變了。那Flutter的Text為什麼又是Statelesswidget的呢?因為Flutter中一切Widget都是 “配置文件”,當我們修改文本之後,Flutter會幫助我們重新初始化一個Text,而不是修改當前的Text對象,這是與原生開發不一樣的地方。
Statefulwidget
Statefulwidget是可變的Widget,在我們的開發中會大量使用Statefulwidget。它實現了一個setState方法,當我們調用這個方法的時候,該Statefulwidget會被重新渲染,注意是重新被渲染,而不是局部更新。
當我們調用setState時,Flutter在收到該消息後,會重新調用其build方法重新構建這個widget,從而達到更新UI的目的。
來看如下代碼:
class StatefulWidgetDemoPage extends StatefulWidget {
@override
_StatefulWidgetDemoPageState createState() => _StatefulWidgetDemoPageState();
}
class _StatefulWidgetDemoPageState extends State<StatefulWidgetDemoPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {});
},
child: Icon(Icons.add),
),
appBar: AppBar(
title: Text("StatefuleWidget Demo"),
centerTitle: true,
backgroundColor: Colors.blue,
),
body: Column(
children: [
Container(
width: 100,
height: 100,
margin: EdgeInsets.all(10),
/// 顏色一個隨機值
color: _randomColor(),
),
],
),
);
}
/// 獲取一個隨機的顏色值
_randomColor() {
return Color.fromARGB(255, Random().nextInt(255), Random().nextInt(255),
Random().nextInt(255));
}
}
我們定義了一個生成隨機顏色的方法_randomColor(),它會返回一個Color對象,然後我們又定義了一個Container,Container的初始化參數color的值是_randomColor()的返回值。然後我們在FloatingActionButton的onPressed的方法中調用一下setState方法,這個時候Flutter會重新繪製StatefulWidgetDemoPage,所以每次點擊按鈕,我們可以看到Container的顏色都是不一樣的。
一切都是Widget
在Flutter中我們看到的UI元素都是由Widget生成的,包括手勢,在Flutter中也是Widget。Widget並不是我們看到的UI元素,我們實際看到的UI元素叫Element,Widget是Element的配置數據。
我們寫了大量的Widget經Flutter處理渲染生成了Element來展示在手機屏幕上。所以當我們調用setState方法的時候,我們只是更新了配置數據,Flutter依照更新後的配置數據來生成新的Element來達到渲染UI的目的。
注意
一個Widget可以對應多個Elememt對象,這等同與一個配置文件可以生成多個實例對象一樣。
想體驗以上的示例的運行效果,可以到我的Github倉庫項目flutter_app->lib->routes->statefulwidget_page.dart查看,並且可以下載下來運行並體驗。