Flutter TabBarView在启动时生成所有选项卡小部件

qmelpv7a  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(173)

我目前正试图得到一个多标签形式的工作。我使用的是flutter_form_builder包。
问题是,FormBuilder要求所有子代表单字段至少加载一次,以运行验证并提供字段的正确值。当用户访问每一个标签页时,事情工作正常,但我不能假设这种情况总是会发生。
在我看来,最简单的解决方案是,以某种方式让TabBarView在启动时呈现所有标签页,以便每个标签部件和表单字段都存在。
我有一个主页面,在那里我定义了表单生成器和它里面的tabview。重要的部分看起来像这样:

@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: 'title',
        bottom: TabBar(
          controller: tabController,
          tabs: <Widget>[
            Tab(icon: Icon(Icons.title)),
            Tab(icon: Icon(Icons.image)),
            Tab(icon: Icon(Icons.category)),
          ],
        ),
      ),
      body: FormBuilder(
          key: formBuilderKey,
          autovalidate: true,
          child: TabBarView(
            controller: tabController,
            children: <Widget>[
              MainTab(),
              CoverTab(),
              GroupsTab()
            ],
          )
        )
    );
}

一个标签页看起来或多或少像这样:

class GroupsTab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return GroupsTabState();
  }
}

class GroupsTabState extends State<GroupsTab> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: EdgeInsets.all(10.0),
      child: Column(
        children: <Widget>[
            FormBuilderTextField(
                attribute: "name",
                decoration: InputDecoration(
                  labelText: "Name",
                  icon: Icon(Icons.title),
                ),
                validators: [FormBuilderValidators.required()],
            ),
            // Page content with form fields
        ],
      ),
    );
  }

  @override
  bool get wantKeepAlive => true;
}

我已经在使用AutomaticKeepAliveClientMixin来只调用每个标签页的构建方法一次,但我需要更多。
所以我的问题是有没有可能让TabBarView在启动时呈现所有的小部件,或者你有一个不同的解决方案的想法。
提前谢谢大家

voase2hg

voase2hg1#

在当前的实现中,Flutter的TabBar小部件中的TabBarView只呈现当前可见的选项卡和相邻选项卡。这样做是出于性能考虑,因为它避免了提前构建所有选项卡,特别是当它们包含繁重或复杂的小部件时。
但是,如果您想确保TabBarView中的所有选项卡都已构建,并且它们的表单字段都已初始化,您可以利用IndexedStack小部件沿着TabBarTabBarView。以下是如何修改代码:
1.将TabBarView更换为IndexedStack

IndexedStack(
  index: tabController.index,
  children: <Widget>[
    MainTab(),
    CoverTab(),
    GroupsTab(),
  ],
)

1.更新GroupsTabbuild方法,以包含Visibility小部件:

@override
Widget build(BuildContext context) {
  super.build(context);
  return Visibility(
    visible: widget.visible,
    maintainState: true,
    child: SingleChildScrollView(
      padding: EdgeInsets.all(10.0),
      child: Column(
        children: <Widget>[
          FormBuilderTextField(
            attribute: "name",
            decoration: InputDecoration(
              labelText: "Name",
              icon: Icon(Icons.title),
            ),
            validators: [FormBuilderValidators.required()],
          ),
          // Other form fields
        ],
      ),
    ),
  );
}

@override
bool get wantKeepAlive => true;

1.在主页中,定义每个选项卡的可见性属性:

bool mainTabVisible = true;
bool coverTabVisible = false;
bool groupsTabVisible = false;

// Inside the build method
IndexedStack(
  index: tabController.index,
  children: <Widget>[
    MainTab(visible: mainTabVisible),
    CoverTab(visible: coverTabVisible),
    GroupsTab(visible: groupsTabVisible),
  ],
)

通过使用IndexedStack,所有的标签页都将在启动时生成,但只显示当前可见的标签页。Visibility小部件确保不可见选项卡中的表单字段在变为可见之前不会被验证或更新。
您可以根据用户交互或应用程序中的任何其他逻辑更新可见性属性(mainTabVisiblecoverTabVisiblegroupsTabVisible),以控制哪些选项卡最初可见。
使用这种方法,您可以确保所有选项卡中的表单字段都已初始化并准备好验证,即使用户最初并没有访问所有选项卡。

相关问题