簡體   English   中英

如何從小部件調用顫動小部件的狀態

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM