widget是fltter界面開發中的基礎控件,如同ios中的uiview這種地位,所謂萬物皆widget。前端
widget有分爲statelessWidget和statefulWidget,這二者是什麼區別呢。一句話就是說statelesswidget用來展現無狀態的視圖,而statefulwidget用來展現可交互的,動態的視圖。ios
到此基本的結論已經出來了,那麼state到底是怎麼實現狀態的更新的?編程
原文發表地址 flutterdev.top小程序
iOS和安卓開發採用的是命令式編程範式,而flutter、前端的VUE,小程序開發採用的是聲明式。bash
如 iosapp
UILable * lable = [UILable new];
label.text = "hello world";
複製代碼
這就是命令式,直接對控件中的屬性進行精準高效的賦值控制。less
然而flutter以下iview
class BgChangeView extends StatefulWidget {
@override
_BgChangeViewState createState() => _BgChangeViewState();
Color color = Colors.red;
}
class _BgChangeViewState extends State<BgChangeView> {
int count = 10;
void _incrementCounter() {
setState(() {
count = count>255 ? 0 :count + 10;
widget.color = Color.fromARGB(count, 0x00, 0xff, 0xff);
print("state refresh count ${count}");
});
}
@override
Widget build(BuildContext context) {
return Container(
width: 100,
height: 100,
child: RaisedButton(onPressed: _incrementCounter,
color: widget.color,
),
);
}
}
複製代碼
將color指定給raisebutton,color在state中更新了,從而更新了raisebuttom的背景顏色ide
state是表示視圖的狀態,當setState觸發當前視圖及其子視圖的銷燬重建,從父視圖到子視圖,從上到下的順序重建。性能
猜想內部state的實現
其實state是負責銷燬重建的,在重建的過程當中從新對widget樹一級級生成,並把外部的數據從新對widget進行賦值操做,由於內部機制小部件重建的效率很高,幾乎肉眼看不到它銷燬的過程,可是若是對於root視圖頻繁進行state的操做,會帶來很大的性能開銷,卡頓,cpu,gpu使用率太高等狀況。這也是聲明式編程一個弊端。使用中須要進來避免過多的setState的操做。
PS: 感謝@Vadasik提醒,賦值一說並不許確,查看了一下setate的源碼並非直接賦值的操做,去除一些異常判斷,如正在刷新,是否已經廢棄,是直接將舊的element加入到dirtyelements中,另外再新建新的element ,調用堆棧,setstate->_element.markNeedsBuild();-->owner.scheduleBuildFor(this); 核心代碼以下:
if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
_scheduledFlushDirtyElements = true;
onBuildScheduled();
}
_dirtyElements.add(element);
element._inDirtyList = true;
複製代碼
flutter engine內部固然會優化這部分的性能,每次重建以後以前申請的widget或randerobject使用的空間不會一個個的清空釋放,而是採起一直滑動壓縮
的方式進行清理。以下圖所示
參考文章