Tabbar flutter 页面间切换报错

Tabbar flutter error switching between page

在 flutter 中创建标签栏并使用作为参考传递的列表浏览各个页面时,页面不再报告正确的数据

每个选项卡包含一个标题和一个字符串列表,此列表显示在每个 TabView 中,但浏览页面不会显示正确的列表。

class _TabsFabDemoState extends State<TabsFabDemo>  with SingleTickerProviderStateMixin {

  @override
  Widget build(BuildContext context) {
  return MaterialApp(
    home: DefaultTabController(
      length: choices.length,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Tabbed AppBar'),
          bottom: TabBar(
            isScrollable: true,
            tabs: choices.map((Choice choice) {
              return Tab(
                text: choice.title,
                icon: Icon(choice.icon),
              );
            }).toList(),
          ),
        ),
        body: Column(
          children: <Widget>[
            GestureDetector(
              onTap: (){
                choices.add(Choice(title: 'CAR', icon: Icons.directions_car));
                setState(() {});
              },
              child: Container(
                height: 100.0,
                color: Colors.red,
              ),
            ),
            Expanded(
              child: TabBarView(
                children: choices.map((Choice choice) {
                  return Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Center(child: ListaLinkWidget(tab: choice)),
                  );
                }).toList(),
              ),
            ),
          ],
        ),
      ),
     ),
    );
  }
}

class Choice {
  Choice({this.title, this.icon});

  final String title;
  final IconData icon;
  List<String> liststring = new List();
}

List<Choice> choices = <Choice>[
  Choice(title: 'CAR', icon: Icons.directions_car),
  Choice(title: 'BICYCLE', icon: Icons.directions_bike),
  Choice(title: 'BOAT', icon: Icons.directions_boat),
  Choice(title: 'BUS', icon: Icons.directions_bus),
  Choice(title: 'TRAIN', icon: Icons.directions_railway),
  Choice(title: 'WALK', icon: Icons.directions_walk),
];



class ListaLinkWidget extends StatefulWidget{

  Choice tab;

  ListaLinkWidget({Key key, this.tab}) : super(key: key);

  @override
  ListaLinkWidgetState createState() => ListaLinkWidgetState();

}

class ListaLinkWidgetState extends State<ListaLinkWidget> {


  @override
  void initState() {
    super.initState();
    widget.tab.liststring.add("a");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Text(
        widget.tab.liststring.toString()
      ),
    );
  }
}

我希望每个页面都有自己的列表,而不是去干扰其他页面的列表,我错了什么?

widget的init块被调用了很多次,如何让它只被调用一次?

谢谢

第 1 步:更改选择 class、添加 this.liststring、删除 = new List()

class Choice {
  Choice({this.title, this.icon, this.liststring});

  final String title;
  final IconData icon;
  List<String> liststring; //= new List();
}    

第二步:选择添加你需要的liststring字符串

List<Choice> choices = <Choice>[
Choice(title: 'CAR', icon: Icons.directions_car, liststring: ["car"]),
Choice(title: 'BICYCLE', icon: Icons.directions_bike, liststring: ["bike"]),

第 3 步:删除 widget.tab.liststring.add("a");

第 4 步:OnTap 需要将 choices.add 更改为 liststring

GestureDetector(
                onTap: () {
                  _counter = _counter + 1;
                  choices.add(Choice(
                      title: 'New ${_counter}',
                      icon: Icons.directions_car,
                      liststring: ['List ${_counter}']));
                  setState(() {});
                },

完整代码

    import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: tabDemo(),
    );
  }
}

class tabDemo extends StatefulWidget {
  @override
  _tabDemoState createState() => _tabDemoState();
}

class _tabDemoState extends State<tabDemo> with SingleTickerProviderStateMixin {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: choices.length,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Tabbed AppBar'),
            bottom: TabBar(
              isScrollable: true,
              tabs: choices.map((Choice choice) {
                return Tab(
                  text: choice.title,
                  icon: Icon(choice.icon),
                );
              }).toList(),
            ),
          ),
          body: Column(
            children: <Widget>[
              GestureDetector(
                onTap: () {
                  _counter = _counter + 1;
                  choices.add(Choice(
                      title: 'New ${_counter}',
                      icon: Icons.directions_car,
                      liststring: ['List ${_counter}']));
                  setState(() {});
                },
                child: Container(
                  height: 100.0,
                  color: Colors.red,
                ),
              ),
              Expanded(
                child: TabBarView(
                  children: choices.map((Choice choice) {
                    return Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Center(child: ListaLinkWidget(tab: choice)),
                    );
                  }).toList(),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class Choice {
  Choice({this.title, this.icon, this.liststring});

  final String title;
  final IconData icon;
  List<String> liststring; //= new List();
}

List<Choice> choices = <Choice>[
  Choice(title: 'CAR', icon: Icons.directions_car, liststring: ["car"]),
  Choice(title: 'BICYCLE', icon: Icons.directions_bike, liststring: ["bike"]),
  /* Choice(title: 'BOAT', icon: Icons.directions_boat),
  Choice(title: 'BUS', icon: Icons.directions_bus),
  Choice(title: 'TRAIN', icon: Icons.directions_railway),
  Choice(title: 'WALK', icon: Icons.directions_walk),*/
];

class ListaLinkWidget extends StatefulWidget {
  Choice tab;

  ListaLinkWidget({Key key, this.tab}) : super(key: key);

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

class ListaLinkWidgetState extends State<ListaLinkWidget>
    with AutomaticKeepAliveClientMixin<ListaLinkWidget> {
  @override
  void initState() {
    super.initState();
    //widget.tab.liststring.add("a");
    print("created");
  }

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      child: Text(widget.tab.liststring.toString()),
    );
  }
}