[英]How to call into a flutter widget's state from the widget
我是 dart/flutter 的新手,並且在理解通信模式方面遇到了一些麻煩。
一個反復出現的問題是,我一直希望在小部件上公開一個公共方法,以便其他小部件可以調用它。
問題在於有狀態的小部件。 在這些情況下,我需要調用小部件狀態來完成實際工作。
問題是小部件沒有狀態的副本。 我一直在小部件中保存狀態的副本,但這當然會引發警告,因為它使小部件可變。
我舉一個具體的例子:
我有一個專門的菜單,可以有一組菜單項。 每個都是有狀態的。
當菜單關閉時,它需要遍歷它擁有的菜單項列表並告訴每個菜單項隱藏(菜單項不可視地包含在菜單中,因此隱藏菜單不起作用)。
所以菜單有以下代碼:
class Menu{
closeMenu() {
for (var menuItem in menuItems) {
menuItem.close();
}
}
所以這工作正常,但當然在 MenuItem 類中我需要:
class MenuItem {
MenuItemState state;
close()
{
state.close();
}
但當然,將狀態對象存儲在 MenuItem 中是一個問題,因為 MenuItem 是不可變的。 (這只是一個警告,所以代碼可以工作,但它顯然不是預期的設計模式)。
我可以通過查看您的更多代碼來更好地了解如何解決您的特定問題,但似乎 Flutter 文檔會在某些方面幫助您,特別是有關提升狀態的部分:
在 Flutter 中,將狀態保持在使用它的小部件之上是有意義的。
為什么? 在像 Flutter 這樣的聲明式框架中,如果你想改變 UI,你必須重建它。
…很難通過調用一個方法從外部強制更改小部件。 即使您可以使這項工作成功,您也會與框架作斗爭,而不是讓它幫助您。
看來您正在嘗試與示例中的框架作斗爭,並且您擔心將公共方法添加到Widget
是正確的。 您需要做的是更接近文檔中詳細說明的內容(其中詳細介紹了您將在下面看到的所有新類等)。 我已經基於此和Provider的使用將一個快速示例放在一起,這使得這種狀態管理方法變得容易。 這是今年鼓勵使用它的Google I/O 演講。
void main() {
runApp(
ChangeNotifierProvider(
builder: (context) => MenuModel(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
…
// call this when the menu is closed
void onMyMenuClosed(BuildContext context) {
var menuModel = getMyMenuModel(context);
menuModel.hideMenuItems();
}
}
class MenuModel extends ChangeNotifier {
bool _displayItems = false;
void hideMenuItems() {
_displayItems = false;
notifyListeners();
}
void showMenuItems() {
_displayItems = true;
notifyListeners();
}
}
調用hideMenuItems()
會調用notifyListeners()
來做到這一點; 通知任何偵聽器更改,這反過來又會提示重建您包裝在Consumer<MenuModel>
中的Widget
/s 現在,當重建顯示菜單的Widget
時,它只會從MenuModel
類中獲取適當的詳細信息 - 那個國家的真相來源。 這將您必須處理的代碼路徑數量減少到一個,並且在您進行進一步更改時更容易查看發生了什么。
@override
Widget build(BuildContext context) {
return Consumer<MenuModel>(
builder: (context, menuModel, child) {
return menuModel._displayItems() ? MenuItemsWidget() : Container();
},
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.