Hot to refresh actions of appBar on tab change?

喜夏-厌秋 提交于 2021-01-29 13:18:21

问题


I'm looking for a way to hide/change appBar actions when specific tab from tabBar is pressed.

Calling setState(() { }) method redrawing entire widget and so all the TabController children/screens, which is real bad.

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 ?


回答1:


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.

So, don't worry about the redrawing of the widget tree, the Flutter team took care of that.




回答2:


Answering my own question:

The fact is we require to call setState((){}) on StatefulWidget in order for it to redraw. So I just moved the code from Widget rightActionButton() to separate class extends from 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. 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();
        },
      ),
    );
  }
  .
  .
}


来源:https://stackoverflow.com/questions/58791044/hot-to-refresh-actions-of-appbar-on-tab-change

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!