Flutter TabBarView 在启动时构建一次所有选项卡小部件

Mor*_*zek 12 dart flutter

我目前正在尝试让多选项卡表单正常工作。我正在使用flutter_form_builder这个包。

问题是,FormBuilder 要求所有后代表单字段至少加载一次才能运行验证并提供字段的正确值。当用户访问每个选项卡时,一切都正常,但我不能假设这种情况总是会发生。

在我看来,最简单的解决方案是以某种方式让 TabBarView 在启动时呈现所有选项卡页面,以便每个选项卡小部件和表单字段都存在。

我有一个主页,我在其中定义表单生成器和其中的选项卡视图。重要的部分如下所示:

@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()
            ],
          )
        )
    );
}
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

我已经使用AutomaticKeepAliveClientMixin只调用每个选项卡页的构建方法一次,但我需要更多。

所以我的问题是:是否可以让 TabBarView 在启动时呈现所有小部件,或者您是否有不同的解决方案的想法。

提前谢谢大家

小智 -1

在您当前的实现中,TabBarViewFlutter 的TabBar小部件仅渲染当前可见的选项卡和相邻选项卡。这样做是出于性能原因,因为它避免了预先构建所有选项卡,特别是当它们包含繁重或复杂的小部件时。

但是,如果您想确保 中的所有选项卡均已TabBarView构建且其表单字段均已初始化,则可以利用该IndexedStack小部件以及TabBarTabBarView。以下是修改代码的方法:

  1. 将 替换TabBarViewIndexedStack
IndexedStack(
  index: tabController.index,
  children: <Widget>[
    MainTab(),
    CoverTab(),
    GroupsTab(),
  ],
)
Run Code Online (Sandbox Code Playgroud)
  1. 更新build您的方法GroupsTab以包含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;
Run Code Online (Sandbox Code Playgroud)
  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),
  ],
)
Run Code Online (Sandbox Code Playgroud)

通过使用IndexedStack,所有选项卡页面将在启动时构建,但仅显示当前可见的选项卡。该Visibility小部件可确保不可见选项卡中的表单字段在变为可见之前不会被验证或更新。

您可以根据用户交互或应用程序中的任何其他逻辑来更新可见性属性 ( mainTabVisiblecoverTabVisible、 ),以控制哪些选项卡最初可见。groupsTabVisible

通过这种方法,您可以确保所有选项卡中的表单字段都已初始化并准备好进行验证,即使用户最初并未访问所有选项卡。