skip to Main Content

In my app I am using a DefaultTabController to display tabs which was working fine but i want to change the Tabbar Tab color when selecting a tab, which was not happening now. I used below code to highlight the selected tab color.

decoration: BoxDecoration(color: tabController?.index == 0 ? highlightColor : normalColor,border: Border.all(color: level1Color6,width: 2,style: BorderStyle.solid),borderRadius: BorderRadius.circular(5)),
            

Below is my complete code :

class TabHome extends StatelessWidget {
TabHome({Key? key}) : super(key: key);

@override
void initState() {
    initState();
}

@override
void dispose() {
    dispose();
}

@override
Widget build(BuildContext context) {
    final screenWidth = getScreenWidth(context);
    final screenHeight = getScreenHeight(context);
    TabController? tabController;

    PreferredSizeWidget sizedAppBar = AppBar(
      title: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
           .....
        ],
      ),
      bottom: PreferredSize(
        preferredSize: Size.fromHeight(50.0),
        child: Container(
        alignment: Alignment.centerLeft,
        padding: EdgeInsets.symmetric(horizontal: 20),
        child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
                  .....
            ],
        ),
        ),
      ),
    );

    PreferredSizeWidget sizedTabBar = TabBar(
        controller: tabController,
        labelColor: textWhite1,
        unselectedLabelColor: Colors.black,
        indicatorWeight: 2,
        isScrollable: true,
        indicatorSize: TabBarIndicatorSize.tab,
        indicatorColor: highlightColor,
        indicatorPadding: EdgeInsets.only(left: 2.0, right: 2.0,bottom: 3.0),
        indicator: BoxDecoration(
            borderRadius: BorderRadius.circular(5), // Creates border
            color: highlightColor,
            shape: BoxShape.rectangle,

        ),
        labelPadding: EdgeInsets.symmetric (horizontal: 1),
        tabs: [
            Container(
            width: mainTabWidth,
            height: mainTabHeight,
            decoration: BoxDecoration(color: tabController?.index == 0 ? highlightColor : normalColor,border: Border.all(color: level1Color6,width: 2,style: BorderStyle.solid),borderRadius: BorderRadius.circular(5)),
            child: Tab(child:Text(tab1,textAlign: TextAlign.center,style: TextStyle(fontSize: fontSize,fontWeight: FontWeight.bold,),),),
            ),
            Container(
            width: mainTabWidth,
            height: mainTabHeight,
            decoration: BoxDecoration(color: tabController?.index == 1 ? highlightColor : normalColor,border: Border.all(color: level1Color6,width: 2,style: BorderStyle.solid),borderRadius: BorderRadius.circular(5)),
            child: Tab(child:Text(tab2,textAlign: TextAlign.center,style: TextStyle(fontSize: fontSize,fontWeight: FontWeight.bold,),),),
            ),
            Container(
            width: mainTabWidth,
            height: mainTabHeight,
            decoration: BoxDecoration(color: tabController?.index == 2 ? highlightColor : normalColor,border: Border.all(color: level1Color6,width: 2,style: BorderStyle.solid),borderRadius: BorderRadius.circular(5)),
            child: Tab(child:Text(tab3,textAlign: TextAlign.center,style: TextStyle(fontSize: fontSize,fontWeight: FontWeight.bold,),),),
            ),
            Container(
            width: mainTabWidth,
            height: mainTabHeight,
            decoration: BoxDecoration(color: tabController?.index == 3 ? highlightColor : normalColor,border: Border.all(color: level1Color6,width: 2,style: BorderStyle.solid),borderRadius: BorderRadius.circular(5)),
            child: Tab(child:Text(tab4,textAlign: TextAlign.center,style: TextStyle(fontSize: fontSize,fontWeight: FontWeight.bold,),),),
            ),
        ],
    );

    final mediaQuery = MediaQuery.of(context);
    final availableHeight = screenHeight - sizedAppBar.preferredSize.height - sizedTabBar.preferredSize.height - mediaQuery.padding.top;

    return MultiBlocProvider(
        providers: [
            BlocProvider(
            create: (context) => TabBloc()..add(TabInitialEvent()),
            )
        ],
        child: MaterialApp(
            scrollBehavior: MyCustomScrollBehavior(),
            title: 'Tab Home',
            debugShowCheckedModeBanner: false,
            home: Scaffold(
            appBar: sizedAppBar,
            body: SafeArea(
                child: Column(
                    children: [
                    SizedBox(height: 3,),
                    DefaultTabController(
                        length: 4, // length of tabs
                        initialIndex: 0,
                        child: Builder(
                            builder: (context) {
                            tabController = DefaultTabController.of(context);
                            tabController?.addListener(() {
                                print("New tab index: ${tabController?.index}");
                            });
                            return Column(
                                    children: <Widget>[
                                    Container(
                                        child: sizedTabBar,
                                    ),
                                    //SizedBox(height: 1.0),
                                    Container(
                                        height: availableHeight * 0.93, //height of TabBarView
                                        decoration: BoxDecoration(
                                            border: Border(top: BorderSide(color: Colors.grey, width: 0.5))
                                        ),
                                        child: TabBarView(
                                        controller: tabController,
                                        children: <Widget>[
                                            Container(
                                            child: Column(
                                                children: [
                                                getFirstTab(screenWidth,screenHeight),
                                                ],
                                            ),
                                            ),
                                            Container(
                                            child: Center(
                                                child: Text('Display Tab 2', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
                                            ),
                                            ),
                                            Container(
                                            child: Center(
                                                child: ElevatedButton(
                                                    child: Text('to Tab 3'),
                                                    onPressed: () {
                                                    print('Tab Now ${tabController?.index}');
                                                    tabController?.animateTo(1);
                                                    }
                                                ),
                                            ),
                                            ),
                                            Container(
                                            child: Center(
                                                child: Text('Display Tab 4', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
                                            ),
                                            ),
                                        ],
                                        ),
                                    ),
                                    ],);
                            }
                        )
                    ),
                    ],
                )
            ),
            ),
        ),
        );
    }

    getFirstTab(double screenWidth, double screenHeight) {
        return BlocBuilder<TabBloc, TabState>(
        builder: (context, state) {
            return Expanded(
                child: Scrollbar(
                controller: controller,
                child: ListView(
                    controller: controller,
                    shrinkWrap: true,
                    children: [
                       .........
                    ],
                ),
                )
            );
        },
        );
    }
}

2

Answers


  1. In your TabBar, you need to notify the view when the tab changes, to rebuild the view again, try this:

    PreferredSizeWidget sizedTabBar = TabBar(
         onTap: (_){
            setState(() {});
         },
         ...
    )
    

    then you need to update you class to StatefulWidget, because you need to update your state.

    Login or Signup to reply.
  2. You have to options to do so.

    The first: is to use stateful widget instead of stateless widget so you can update the current page state using

    setState((){});
    

    The second: is to use one of the state management like getX, Provider, Bloc .. etc.

    this will help you with bigger projects even if you’re using stateless widget
    you can update your current state so you can make changes to your screen while using Bloc you can do emit(YourStateHere());

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search