用于从子窗口小部件更新TabController长度的模式

时间:2017-09-12 15:58:52

标签: flutter

主页面有很多子窗口小部件。搜索时,会显示SearchWidget,否则会显示DashletsWidget

DashletsWidgetTabControllerTabController保留在主页面中,因此搜索后不会重置活动标签。

DashletsWidget有一个dashlet设置窗格,可能会更改标签数量。

DashletsWidget(ValueNotifier<int> dashletCount, TabController controller)使用ValueNotifier让父母重新创建controller :.在重新创建时,旧的TabController无法可靠地处理,因此请在不进行处理的情况下进行解除引用。这是一种工作,但非常自然。是否有一个好的模式来更新TabController.length

4 个答案:

答案 0 :(得分:3)

作为Kyaw,我正在努力按需调整TabController.length,在状态更改时(在setState上,在构建之前,在didUpdateWidget上)创建新的TabController。但是,我不确定为什么这行不通。

我正在做的(并且正在工作)正在使用制表符控制器的长度,就好像它是“最大长度”一样。因此,由于我的应用程序的业务逻辑最多定义20个制表符,因此这就是我使用的长度(20)。我在TabController上创建了一个固定长度一次initState(),并在dispose()上进行了一次的处理。

尽管如此,只要TabBarTabBarView的选项卡和子项正确放置,例如两个项都正确放置,它们的UI就可以像预期的那样对2个项起作用。

它正在正常工作! (我知道):)

答案 1 :(得分:1)

将未使用的TabController垃圾收集起来很不错。

这是另一种可能感觉更好的策略:您可以在State所拥有的模型对象中存储有关选项卡数量的信息,而不是DashletsWidget。 1}},并将该模型对象作为配置值传递给DashletsWidget。如果重建DashletsWidget并且构造函数参数发生更改,则会调用didUpdateWidget DashletsWidgetState方法,您可以将其用作替换TabController的机会。或者,您可以使用标签数量为ValueKey构建DashletsWidget,因此更改标签配置会自动dispose现有DashletsWidgetState并将其替换为新标签。

答案 2 :(得分:0)

我找到了自己的更新TabController长度的方法。

我在initState()中使用假长度对其进行了初始化,该长度仅类似于占位符。当我知道TabController应该具有的正确长度时,我再次对其进行了初始化,但是现在具有正确的长度。这是我的意思:

TabController _tabController;

@override
  void initState() {
    super.initState();

    // Initialize the TabController with a fake length
    _tabController = TabController(vsync: this, length: 0);

    // Retrieve the number of tabs that will be displayed in TabBar
    _retrieveNumOfTabs().then((numOfTabs) {
      // Initialize the TabController with the right length
      _tabController = TabController(vsync: this, length: numOfTabs);

     // Add here all the controller's listeners
    });
  }

答案 3 :(得分:0)

使用DefaultTabController:

  List<String> tabNames = ["a", "b", "C"];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: tabNames.length,
        child: Scaffold(
          // add new tab on click
          floatingActionButton: FloatingActionButton(
              onPressed: () => setState(() {
                    tabNames.add("c");
                  })),
          appBar: AppBar(bottom: TabBar(tabs: tabNames.map((x) => Tab(text: x)).toList())),
          body: TabBarView(children: tabNames.map((x) => Container(child: Text(x))).toList()),
        ));
  }

如果您使用的是棉条,还请添加:

TabBar(controller: DefaultTabController.of(context), ...)

使用TabController:

  List<String> tabNames = ["a", "b", "C"];
  TabController _controller;

  @override
  void initState() {
    super.initState();
    _controller = TabController(vsync: this, length: tabNames.length);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // add new tab on click
      floatingActionButton: FloatingActionButton(
          onPressed: () => setState(() {
                tabNames.add("c");
                // might be good idea to dispose old tabController before
                _controller = TabController(vsync: this, length: tabNames.length);
              })),
      appBar: AppBar(bottom: TabBar(controller: _controller, tabs: tabNames.map((x) => Tab(text: x)).toList())),
      body: TabBarView(controller: _controller, children: tabNames.map((x) => Container(child: Text(x))).toList()),
    );
  }