Search code examples
flutterdartflutter-layouttabbardisable

Flutter: How to disable a particular tab, in TabBar


I am trying to disable a particular tab in my TabBar. For example if index is 1, I want to disable tab in index 1. I’m not able to do so.

Here is TabBar Example

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>    with SingleTickerProviderStateMixin {
late  TabController _tabController;

  @override
  void initState() {
    _tabController = TabController(length: 2, vsync: this);
    super.initState();
  }
  
  
    void changeScheduleTabbar(int index) {
      print(index);
     if(index==0){
      setState(() {
         _tabController.index = index >= 0 && index < 2 ? index : 0;
      });  
     } 
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:const Text(
          'Tab bar',
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: [
            Container(
              height: 45,
              decoration: BoxDecoration(
                color: Colors.grey[300],
                borderRadius: BorderRadius.circular(
                  25.0,
                ),
              ),
              child: TabBar(
                controller: _tabController,
                indicator: BoxDecoration(
                  borderRadius: BorderRadius.circular(
                    25.0,
                  ),
                  color: Colors.green,
                ),
                onTap: (int index) =>changeScheduleTabbar(index), //<<=========== control Tab change here 
                labelColor: Colors.white,
                unselectedLabelColor: Colors.black,
                tabs: const[
                  //<<=== first tab 
                  Tab(
                    text: 'Place Bid',
                  ),

                  //<<=== second tab
                  Tab(
                    text: 'Buy Now',
                  ),
                ],
              ),
            ),
            // tab bar view here
            Expanded(
              child: TabBarView(
                controller: _tabController,
                children:const [
                  // first tab bar view widget 
                  Center(
                    child: Text(
                      'Place Bid',
                      style: TextStyle(
                        fontSize: 25,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),

                  // second tab bar view widget
                  Center(
                    child: Text(
                      'Buy Now',
                      style: TextStyle(
                        fontSize: 25,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Where is the problem ? How can I solve this issue?


Solution

  • The issue is you are trying to directly assign the index to _tabController.index.

    Instead for a certain condition, you should assign the previous index of the tab controller like so: tabController.index = index == 1? tabController.previousIndex : index;

    Here is the whole code with three tabs for easier understanding: (I've updated the code a bit for better organisation)

    import 'package:flutter/material.dart';
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({
        Key? key,
        required this.title,
      }) : super(key: key);
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      late TabController _tabController;
    
      List<Tab> tabs = const [
        Tab(text: 'Place Bid'),
        Tab(text: 'Buy Now'),
        Tab(text: 'Sell Now'),
      ];
    
      @override
      void initState() {
        _tabController = TabController(length: tabs.length, vsync: this);
        super.initState();
      }
    
      void onTap(int index) {
        setState(() {
          _tabController.index = index == 1 ? _tabController.previousIndex : index;
        });
      }
    
      @override
      void dispose() {
        super.dispose();
        _tabController.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Tab bar'),
          ),
          body: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              children: [
                Container(
                  height: 45,
                  decoration: BoxDecoration(
                    color: Colors.grey[300],
                    borderRadius: BorderRadius.circular(25.0),
                  ),
                  child: TabBar(
                    controller: _tabController,
                    indicator: BoxDecoration(
                      borderRadius: BorderRadius.circular(25.0),
                      color: Colors.green,
                    ),
                    onTap: (int index) => onTap(index),
                    labelColor: Colors.white,
                    unselectedLabelColor: Colors.black,
                    tabs: tabs,
                  ),
                ),
                Expanded(
                  child: TabBarView(
                    controller: _tabController,
                    children: const [
                      BidTab(),
                      BuyTab(),
                      SellTab(),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class SellTab extends StatelessWidget {
      const SellTab({
        Key? key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'Sell Now',
            style: TextStyle(
              fontSize: 25,
              fontWeight: FontWeight.w600,
            ),
          ),
        );
      }
    }
    
    class BuyTab extends StatelessWidget {
      const BuyTab({
        Key? key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'Buy Now',
            style: TextStyle(
              fontSize: 25,
              fontWeight: FontWeight.w600,
            ),
          ),
        );
      }
    }
    
    class BidTab extends StatelessWidget {
      const BidTab({
        Key? key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: Text(
            'Place Bid',
            style: TextStyle(
              fontSize: 25,
              fontWeight: FontWeight.w600,
            ),
          ),
        );
      }
    }