skip to Main Content

i am trying to change tabs programmatically with clicking a button
so when i run the code everything is okay i click on the fab button and the tabs changes correctly and you can see the index numbers in debug console too … until the moment that selected tabs is the last one and in that moment when i click on the button i get an error . that i really don’t understand it . and i really don’t know what to do.

here is my code:

class MyHome extends StatefulWidget {
  const MyHome({super.key});

  @override
  State<MyHome> createState() => _MyHomeState();
}

class _MyHomeState extends State<MyHome> with SingleTickerProviderStateMixin {
  late TabController _controller;
  int _selectedIndex = 0;

  @override
  void initState() {
    super.initState();
    _controller = TabController(length: 5, vsync: this);

    //listener adding...
    _controller.addListener(() {
      setState(() {
        _selectedIndex = _controller.index;

      });
      print("Selected Index: " + _controller.index.toString());
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 5,
      child: Scaffold(
        floatingActionButton: FloatingActionButton(onPressed: () {
          _controller.animateTo(_selectedIndex += 1);
        }),
        body: NestedScrollView(
            headerSliverBuilder: (context, innerBoxIsScrolled) {
              return [
                SliverAppBar(
                  title: const Text('WELCOME'),
                  floating: true,
                  pinned: true,
                  bottom: TabBar(controller: _controller, tabs: const [
                    Tab(child: Text('Flight')),
                    Tab(child: Text('Train')),
                    Tab(child: Text('Car')),
                    Tab(child: Text('Cycle')),
                    Tab(child: Text('Boat')),
                  ]),
                )
              ];
            },
            body: TabBarView(controller: _controller, children: const [
              Icon(Icons.flight, size: 350),
              Icon(Icons.directions_transit, size: 350),
              Icon(Icons.directions_car, size: 350),
              Icon(Icons.directions_bike, size: 350),
              Icon(Icons.directions_boat, size: 350),
            ])),
      ),
    );
  }
}

and here is the error message :

2

Answers


  1. There is no distinction in cases where _selectedIndex is equal to last.

    floatingActionButton: FloatingActionButton(onPressed: () {
      if (_selectedIndex == 4) {
        _controller.animateTo(_selectedIndex = 0);
      } else {
        _controller.animateTo(_selectedIndex += 1);
      }
    }),
    
    Login or Signup to reply.
  2. The problem is that your exceeding the length of the tabs. You need to first check the amount of tabs before animating:

     floatingActionButton: FloatingActionButton(onPressed: () {
              // check if the index is less than the length of the tabs
              if (_selectedIndex < _controller.length - 1) {
                _controller.animateTo(_selectedIndex += 1);
              }
            }),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search