Question: I have been trying to add listeners when using `DefaultTabController`. However, every time I add a `TabController` in order to get the current index in either `TabBar` and `TabBarView`, I lose sync between them.

This is my code below: 

```
  @override
  Widget build(BuildContext context) {
    return new DefaultTabController(
      length: subPages.length,
      child: new Scaffold(
        appBar: appBar('homepage'),
        body: new Center(
          child: new NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                new SliverAppBar(
                  backgroundColor: Colors.white,
                  title: new TabBar(
                    labelColor: Colors.black,
                    indicatorColor: Colors.black,
                    labelStyle: new TextStyle(fontWeight: FontWeight.bold),
                    tabs: subPages.map((String str) => new Tab(text: str)).toList(),
                  ),
                ),
              ];
            },
            body: new TabBarView(
              children: subPages.map((String str) {
                return new ListView(
                  padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
                  children: subPages.map((String str) {
                    return new Padding(
                      padding: const EdgeInsets.symmetric(vertical: 8.0),
                      child: new Text(str),
                    );
                  }).toList(),
                );
              }).toList(),
            ),
          ),
        ),
        floatingActionButton: new FloatingActionButton(
          backgroundColor: Colors.black,
          onPressed: null,
          tooltip: 'Increment',
          child: new Icon(Icons.add),
        ),
      ),
    );
  }

```

Answer: 
I use this:

```
new DefaultTabController(
  child: Builder(
    builder: (context) {

      final tabController = DefaultTabController.of(context)!;
      tabController.addListener(() {
        print("New tab index: ${tabController.index}");
      });

      return Scaffold(
        ...
      );
    }
  ),
);

```
1. Define a tabController and a listener (once changing tab, it will be triggered twice)

```dart
class _ScreenState extends State<Screen> with SingleTickerProviderStateMixin {
  late TabController tabController;

  @override
  void initState() {
    super.initState();
    this.tabController = TabController(length: 3, vsync: this);
    this.tabController.addListener(() {
      if (this.tabController.indexIsChanging) {
        print(this.tabController.index);
        print(this.tabController.previousIndex);
      }
    });
  }
}

```

2. Pass it to the TabBar and TabBarView, like:

```dart
TabBar(
  controller: this.tabController,
  tabs: [
   Tab(text: "0"),
   Tab(text: "1"),
   Tab(text: "2"),
  ],
)

TabBarView(controller: this.tabController, children: [...])

```