首页 > 解决方案 > Flutter:动态添加选项卡并使用 AutomaticKeepAliveClientMixin 保持状态

问题描述

我正在尝试创建一个带有标签的表单。在每个选项卡中,我都有 TextFormField。选项卡有 AutomaticKeepAliveClientMixin 来保持它们的状态。选项卡可以动态创建。创建新选项卡时,它会插入到选项卡列表的中间。

问题:插入新选项卡时,其 TextFormField 保持下一个选项卡的状态,依此类推。似乎状态保持从 1 到 n 的顺序。有没有办法保持标签的正确状态?

提前致谢。

import 'package:flutter/material.dart';

class TabTesting extends StatefulWidget {
  @override
  _TabTestingState createState() => _TabTestingState();
}

class _TabTestingState extends State<TabTesting> with TickerProviderStateMixin {

  List<MyTab> _tabs = [
      MyTab(TabData("1", "1")),
      MyTab(TabData("3", "3")),
  ];

  TabController _tabController;

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

    _tabController = new TabController(vsync: this, length: _tabs.length);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("TabTesting"),
        bottom: TabBar(
          controller: _tabController,
          labelPadding: EdgeInsets.symmetric(vertical: 16.0),
          tabs: _tabs.map((tab) => Text(tab.tabData.name)).toList(),
        ),
      ),
      body: Container(
        padding: EdgeInsets.all(32.0),
        child: TabBarView(
          controller: _tabController,
          children: _tabs,
        ),
      ),
      persistentFooterButtons: <Widget>[
        RaisedButton(
          child: Text("Add tab"),
          onPressed: () {
            final newTab = MyTab(TabData("2", "2"));
            final newTabs = _tabs;
            newTabs.insert(1, newTab);
            final index = _tabController.index;
            setState(() {
              _tabs = newTabs;             
              _tabController = TabController(
                  vsync: this,
                  length: newTabs.length,
                  initialIndex: index);
            });
          },
        ),
      ],
    );
  }
}

class MyTab extends StatefulWidget {

  final tabData;

  MyTab(this.tabData);

  @override
  _MyTabState createState() => _MyTabState();
}

class _MyTabState extends State<MyTab> with AutomaticKeepAliveClientMixin {

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    return Tab(
      child: TextFormField(
        decoration: InputDecoration(labelText: widget.tabData.name),
        initialValue: widget.tabData.data,
      ),
    );
  }
}

class TabData {
  String name;
  String data;

  TabData(this.name, this.data);
}

标签: tabsdartflutterstate

解决方案


您忘记按照AutomaticKeepAliveClientMixinsuper.build(context);的文档建议添加。

@override
  Widget build(BuildContext context) {
    super.build(context);
    return Tab(
      child: TextFormField(
        decoration: InputDecoration(labelText: widget.tabData.name),
        initialValue: widget.tabData.data,
      ),
    );
  }

推荐阅读