Flutter StatefulBuilder實(shí)現(xiàn)局部刷新實(shí)例詳解
前言
flutter項(xiàng)目中,在頁(yè)面數(shù)據(jù)較多的情況下使用全量刷新對(duì)性能消耗較大且容易出現(xiàn)短暫白屏的現(xiàn)象,出于性能和用戶(hù)體驗(yàn)方面的考慮我們經(jīng)常會(huì)使用局部刷新代替全量刷新進(jìn)行頁(yè)面更新操作。
GlobalKey、ValueNotifier和StreamBuilder等技術(shù)方案都可以實(shí)現(xiàn)Flutter頁(yè)面的局部刷新,本文主要記錄的是通過(guò)StatefulBuilder組件來(lái)實(shí)現(xiàn)局部刷新的方法。
頁(yè)面的全量刷新
在StatefulWidget內(nèi)直接調(diào)用setState方法更新數(shù)據(jù)時(shí),會(huì)導(dǎo)致頁(yè)面重新執(zhí)行build方法,使得頁(yè)面被全量刷新。
我們可以通過(guò)以下案例了解頁(yè)面的刷新情況:
int a = 0;
int b = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 點(diǎn)擊按鈕,數(shù)據(jù)‘a(chǎn)'加1,并刷新頁(yè)面
ElevatedButton(
onPressed: () {
a++;
setState(() {});
},
child: Text('a : $a'),
),
// 點(diǎn)擊按鈕,數(shù)據(jù)‘b'加1,并刷新頁(yè)面
ElevatedButton(
onPressed: () {
b++;
setState(() {});
},
child: Text('b : $b'),
),
],
),
),
);
}
代碼運(yùn)行效果如圖:

當(dāng)我們點(diǎn)擊第一個(gè)ElevatedButton組件時(shí),會(huì)執(zhí)行a++和setState(() {})語(yǔ)句。通過(guò)系統(tǒng)的Flutter Performance工具我們可以捕獲到組件刷新的情況,當(dāng)執(zhí)行到setState(() {})時(shí),頁(yè)面不只是刷新a數(shù)據(jù)所在的ElevatedButton組件,而是重新構(gòu)建了頁(yè)面,這會(huì)造成額外的性能消耗。


出于性能的考慮,我們更希望當(dāng)點(diǎn)擊第一個(gè)ElevatedButton組件時(shí),系統(tǒng)只對(duì)a數(shù)據(jù)進(jìn)行更新,b作為局外人不參與此次活動(dòng)。我們可以通過(guò)StatefulBuilder組件來(lái)實(shí)現(xiàn)這個(gè)功能。
StatefulBuilder簡(jiǎn)介
StatefulBuilder組件包含了兩個(gè)參數(shù),其中builder參數(shù)為必傳,不能為空:
const StatefulBuilder({
Key? key,
required this.builder,
}) : assert(builder != null),
super(key: key);
builder 包含了兩個(gè)參數(shù),一個(gè)頁(yè)面的context,另一個(gè)是用于狀態(tài)改變時(shí)觸發(fā)重建的方法:
typedef StatefulWidgetBuilder = Widget Function(BuildContext context, StateSetter setState); final StatefulWidgetBuilder builder;
StatefulBuilder的實(shí)際應(yīng)用
StatefulBuilder組件在實(shí)際應(yīng)用中主要分成以下操作:
- 1、定義一個(gè)
StateSetter類(lèi)型的方法; - 2、將需要局部刷新數(shù)據(jù)的組件嵌套在
StatefulBuilder組件內(nèi); - 3、調(diào)用第1步定義的
StateSetter類(lèi)型方法對(duì)StatefulBuilder內(nèi)部進(jìn)行刷新;
int a = 0;
int b = 0;
// 1、定義一個(gè)叫做“aState”的StateSetter類(lèi)型方法;
StateSetter? aState;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 2、將第一個(gè)“ElevatedButton”組件嵌套在“StatefulBuilder”組件內(nèi);
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
aState = setState;
return ElevatedButton(
onPressed: () {
a++;
// 3、調(diào)用“aState”方法對(duì)“StatefulBuilder”內(nèi)部進(jìn)行刷新;
aState(() {});
},
child: Text('a : $a'),
);
},
),
ElevatedButton(
onPressed: () {
b++;
setState(() {});
},
child: Text('b : $b'),
),
],
),
),
);
}
重新運(yùn)行后點(diǎn)擊第一個(gè)按鈕對(duì)a進(jìn)行累加時(shí),通過(guò)Flutter Performance工具我們可以了解到,只有StatefulBuilder組件及其包含的組件被重新構(gòu)建,實(shí)現(xiàn)了局部刷新的功能,有效的提高了頁(yè)面的性能;


總結(jié)
StatefulWidget內(nèi)更新一個(gè)屬性會(huì)導(dǎo)致整個(gè)樹(shù)重新構(gòu)建,為防止這種不必要的性能消耗,可以通過(guò)StatefulBuilder組件進(jìn)行局部刷新,有效的提高性能。
以上就是Flutter StatefulBuilder實(shí)現(xiàn)局部刷新實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于Flutter StatefulBuilder局部刷新的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android自定義View繪圖實(shí)現(xiàn)漸隱動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了Android自定義View繪圖實(shí)現(xiàn)漸隱動(dòng)畫(huà),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Android教你如何發(fā)現(xiàn)APP卡頓的實(shí)現(xiàn)
這篇文章主要介紹了Android教你如何發(fā)現(xiàn)APP卡頓的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Android自定義UI手勢(shì)密碼改進(jìn)版源碼下載
這篇文章主要介紹了Android自定義UI手勢(shì)密碼改進(jìn)版,為大家提供了手勢(shì)密碼源碼下載,,具有一定的實(shí)用性,感興趣的小伙伴們可以參考一下2016-10-10
用Android?studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了用Android?studio實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android 判斷網(wǎng)絡(luò)狀態(tài)實(shí)例詳解
這篇文章主要介紹了Android 判斷網(wǎng)絡(luò)狀態(tài)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04
Android實(shí)現(xiàn)每天定時(shí)提醒功能
本文主要介紹了Android每天定時(shí)提醒功能、定時(shí)功能、鬧鐘的相關(guān)知識(shí)。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-04-04
使用Android Studio Gradle實(shí)現(xiàn)友盟多渠道打包
這篇文章主要介紹了使用Android Studio Gradle實(shí)現(xiàn)友盟多渠道打包,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Android開(kāi)發(fā)之底圖局部加載移動(dòng)的方法示例
這篇文章主要介紹了Android開(kāi)發(fā)之底圖局部加載移動(dòng)的方法,涉及Android針對(duì)圖片與屏幕屬性的讀取、計(jì)算、設(shè)置等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08

