如何管理彈窗中復選框的選中狀態(tài)?習慣上,我們會在路由頁的State中來管理選中狀態(tài)义锥,我們可能會:
setState(() {
//更新復選框狀態(tài)
withTree = !withTree;
});
然后,當我們運行上面的代碼時我們會發(fā)現(xiàn)復選框根本選不中岩灭!為什么會這樣呢拌倍?其實原因很簡單,我們知道setState方法只會針對當前context的子樹重新build噪径,但是我們的對話框并不是在_DialogRouteState的build 方法中構(gòu)建的柱恤,而是通過showDialog單獨構(gòu)建的,所以在_DialogRouteState的context中調(diào)用setState是無法影響通過showDialog構(gòu)建的UI的找爱。另外膨更,我們可以從另外一個角度來理解這個現(xiàn)象,前面說過對話框也是通過路由的方式來實現(xiàn)的缴允,那么上面的代碼實際上就等同于企圖在父路由中調(diào)用setState來讓子路由更新,這顯然是不行的珍德!簡爾言之练般,根本原因就是context不對。那如何讓復選框可點擊呢锈候?通常有如下三種方法:
一薄料、單獨抽離出StatefulWidget
缺點:對話框上所有可能會改變狀態(tài)的組件都得單獨封裝在一個在內(nèi)部管理狀態(tài)的StatefulWidget中,這樣不僅麻煩泵琳,而且復用性不大摄职。
二、使用StatefulBuilder方法
自己的理解:實際上获列,這種方法本質(zhì)上就是子組件通知父組件(StatefulWidget)重新build子組件本身來實現(xiàn)UI更新的谷市。如果你需要改變的變量是全局的,那么這種方法就不會去改變?nèi)值淖兞炕骱ⅲ褪亲饔糜虻膯栴}迫悠。
//使用StatefulBuilder來構(gòu)建StatefulWidget上下文
StatefulBuilder(
builder: (context, _setState) {
return Checkbox(
value: _withTree, //默認不選中
onChanged: (bool value) {
//_setState方法實際就是該StatefulWidget的setState方法,
//調(diào)用后builder方法會重新被調(diào)用
_setState(() {
//更新選中狀態(tài)
_withTree = !_withTree;
});
},
);
},
),
三巩梢、精妙的解法创泄,個人覺得這是最簡單的方法
// 通過Builder來獲得構(gòu)建Checkbox的`context`,
// 這是一種常用的縮小`context`范圍的方式
Builder(
builder: (BuildContext context) {
return Checkbox(
value: _withTree,
onChanged: (bool value) {
(context as Element).markNeedsBuild();
_withTree = !_withTree;
},
);
},
),