简体   繁体   English

如何在标签更改时刷新 appBar 的操作?

[英]How to refresh actions of appBar on tab change?

I'm looking for a way to hide/change appBar actions when specific tab from tabBar is pressed.我正在寻找一种在按下 tabBar 的特定选项卡时隐藏/更改 appBar 操作的方法。

Calling setState(() { }) method redrawing entire widget and so all the TabController children/screens, which is real bad.调用setState(() { })方法重绘整个小部件以及所有 TabController 子/屏幕,这真的很糟糕。

Below is my code:下面是我的代码:

enum SelectedTab {
  items, sales, raw_items, orders
}

class _MyHomePageState extends State<MyHomePage>
{
  Widget rightActionButton(BuildContext context)
  {
    //This is the widget which is expected to be update upon tab change

    SelectedTab currentTab = Globals.instance.selectedTab;

    return Visibility (
      child: . . .
      visible: currentTab != SelectedTab.sales,
    );
  }

  Widget navBar(BuildContext context)
  {
    return AppBar(
      title: Text('Example'),
      actions: <Widget>[
        rightActionButton(context),
      ],
    );
  }

  Widget tabBar(BuildContext context)
  {
    return Container(
      child: TabBar(
        tabs: [ 
          . . . .
        ],
        onTap: (index) {
          Globals.instance.selectedTab = SelectedTab.values[index];
          //Refresh rightActionButton
        },
      ),
    );
  }

  Widget tabScreens(BuildContext context) {
    return TabBarView(
      children: [
        . . . . 
      ],
    );
  }

  @override
  Widget build(BuildContext context)
  {
    return DefaultTabController(
      length: 4,
      child: Scaffold (
        appBar: navBar(context),
        bottomSheet: tabBar(context),
        body: tabScreens(context),
      ),
    );
  }
}

How can we redraw actions of the appBar only instead of redrawing all the widgets in scaffold?我们如何actions of the appBar only而不是重绘脚手架中的所有小部件?

Answering my own question:回答我自己的问题:

The fact is we require to call setState((){}) on StatefulWidget in order for it to redraw.事实上,我们需要在 StatefulWidget 上调用 setState((){}) 以使其重绘。 So I just moved the code from Widget rightActionButton() to separate class extends from StatefulWidget.所以我只是将代码从Widget rightActionButton()移到了 class 从 StatefulWidget 扩展。

class ActionButton extends StatefulWidget
{
  final ActionButtonState abs = ActionButtonState();
  void refresh() {
    abs.refresh();
  }
  @override
  ActionButtonState createState() =>  abs;
}

class  ActionButtonState extends State<ActionButton>
{ 
  void refresh() { 
    setState(() {}); 
  }

  @override
  Widget build(BuildContext context)
  {
    SelectedTab currentTab = Globals.instance.selectedTab;

    return Visibility ( ... )
  }
}

And then we can just call refresh() method of ActionButton instance wherever its used.然后我们可以在任何使用的地方调用 ActionButton 实例的 refresh() 方法。 Like:喜欢:

class _MyHomePageState extends State<MyHomePage>
{
  ActionButton actionButton1 = new ActionButton();

  Widget navBar(BuildContext context)
  {
    return AppBar(
      title: Text('Example'),
      actions: <Widget>[
        actionButton1,
      ],
    );
  }

  Widget tabBar(BuildContext context)
  {
    return Container(
      child: TabBar(
        tabs: [ 
          . . . .
        ],
        onTap: (index) {
          Globals.instance.selectedTab = SelectedTab.values[index];
          actionButton1.refresh();
        },
      ),
    );
  }
  .
  .
}

In Flutter, when you call setState() , it will automatically track which widgets depend on the data that was changed in setState() function and rebuilds the parts of your tree that have changed, not the whole widget.在 Flutter 中,当您调用setState()时,它将自动跟踪哪些小部件取决于在setState() function 中更改的数据,并重建树中已更改的部分,而不是整个小部件。

So, don't worry about the redrawing of the widget tree, the Flutter team took care of that.所以,不用担心小部件树的重绘,Flutter 团队负责处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM