A simple demo

class _RankPageState extends State<RankPage>{
  final List<Tab> titleTabs = <Tab>[
    Tab(
      text: Live List of the Day,
    ),
    Tab(
      text: 'Yesterday's Chart',
    ),
    Tab(
      text: 'Last Week's Standings',)]; . child: Scaffold( appBar: AppBar( ... elevation:0.0,
          backgroundColor: Color.fromRGBO(26.172.255.1),
          title: TabBar(
            isScrollable: true,
            indicator: UnderlineTabIndicator(
                borderSide: BorderSide(style: BorderStyle.none)),
            tabs: titleTabs
          ),
        ),
        body: Container(
          color: Color.fromRGBO(26.172.255.1),
          child: TabBarView(
            / / TabBarView default gestures sliding support, if you want to set NeverScrollableScrollPhysics is prohibited
            physics: NeverScrollableScrollPhysics(),
            children: <Widget>[
                Center(child:Text('view1')),
                Center(child:Text('view2')),
                Center(child:Text('view3'() (() (() (() (() (() ( }Copy the code

TabBar has a one-to-one relationship with TabBarView through index, and DefaultTabController is provided by default to establish the relationship between the two. To switch animation and listen to switch interaction, you can define a Controller

class _RankPageState extends State<RankPage> with SingleTickerProviderStateMixin{... TabController tabController;@override
  void initState() {
    super.initState();
    // Add a listener
    tabController = TabController(vsync: this, length: titleTabs.length) .. addListener(() {switch (tabController.index) {
            case 0:
              print(1);
              break;
            case 1:
              print(2)
              break;
            case 2:
              print(3)
              break; }}); }.../ / add the controllertitle: TabBar( controller: tabController, ... ) . child: TabBarView( controller: tabController, ... ) . }Copy the code

Check the result after running, each time switch TAB console will print the corresponding value, but there is a problem, click the TAB to switch printed twice, it seems to execute twice, slide switch normal output once. The reason for this is that the click triggers notifyListeners() in sequence during the animation; The source code is as follows:

-Github Issues





// This animation represents the current TabBar selected indicator position and the scrollOffsets of the TabBar and TabBarViewAnimation, animation <double>
// The subscript of Tab is currently selected. Changing index also updates the previousIndex, sets the animation's value, resets indexIsChanging to false, and notifies the listenerThe index ↔int
//true: when the animation jumps from one animation to the nextIndexIsChanging -bool
// The total number of tabs, usually greater than 1Length -int
// Different from animation's value and index. The offset value must be between -1.0 and 1.0Offset ↔double
// The index value of the previous TAB selection is initially the same as indexPreviousIndex -int
Copy the code

So we can add another layer of judgment in the listener

. tabController = TabController(vsync:this, length: titleTabs.length) .. addListener(() {if(tabController.indexIsChanging){
            switch (tabController.index) {
                case 0:
                  print(1);
                  break;
                case 1:
                  print(2)
                  break;
                case 2:
                  print(3)
                  break; }}}); .Copy the code

This solved the problem of clicking to execute a code block twice, but indexIsChanging is always false when we try sliding, meaning that sliding does not execute our code… After a bit of trial and error, we made the following changes so that both swipes and clicks execute our code block once

. tabController = TabController(vsync:this, length: titleTabs.length) .. addListener(() {if(tabController.index.toDouble() == tabController.animation.value){
            switch (tabController.index) {
                case 0:
                  print(1);
                  break;
                case 1:
                  print(2)
                  break;
                case 2:
                  print(3)
                  break; }}}); .Copy the code

Well, that’s what we need…

reference

The official TabController API