【问题标题】:How to refresh actions of appBar on tab change?如何在标签更改时刷新 appBar 的操作?
【发布时间】:2020-03-06 12:45:32
【问题描述】:

我正在寻找一种在按下 tabBar 的特定选项卡时隐藏/更改 appBar 操作的方法。

调用 setState(() { }) 方法重绘整个小部件以及所有 TabController 子/屏幕,这真的很糟糕。

下面是我的代码:

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),
      ),
    );
  }
}

我们如何重绘actions of the appBar only而不是重绘脚手架中的所有小部件?

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    回答我自己的问题:

    事实上,我们需要在 StatefulWidget 上调用 setState((){}) 以使其重绘。所以我只是将代码从 Widget rightActionButton() 移到了从 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 ( ... )
      }
    }
    

    然后我们可以在任何使用的地方调用 ActionButton 实例的 refresh() 方法。喜欢:

    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();
            },
          ),
        );
      }
      .
      .
    }
    

    【讨论】:

      【解决方案2】:

      在 Flutter 中,当您调用 setState() 时,它会自动跟踪哪些小部件依赖于在 setState() 函数中更改的数据,并重建树中已更改的部分,而不是整个小部件。

      所以,不用担心小部件树的重绘,Flutter 团队会处理这个问题。

      【讨论】:

      • 你的意思是调用setState(() { //change global variable here }),而不是调用空的setState(() {}),所以唯一可见性取决于该全局变量的小部件Visibility将是重绘?
      • 是的,我也推荐阅读article 了解 setState() 方法的最佳实践。
      • 不,调用 setState() 正在重绘所有小部件,无论我们是否更改其中的任何内容。我想我需要使 Visiblity 小部件有状态,所以我调用 setState :) 谢谢。
      猜你喜欢
      • 1970-01-01
      • 2011-10-23
      • 2016-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      相关资源
      最近更新 更多