Timothy Ndichu
Timothy Ndichu

Reputation: 81

How to change decoration of a Tab based on its index?

I am trying to design my tabs as the design below:
tab controller

I have been able to design it like that but my problem is how to change the decoration of the selected tab container based on it's index. As in the picture above, the Nike logo tab is selected.
By default, I can only change the color of the icon in the selected tab.
So I thought of checking for index, so I can change the decoration of the container based on whether the tab is selected or not.

I however, I am unable to do so.

Code:

class HomePage extends StatefulWidget {
  const HomePage({
    Key key,
    @required this.height,
    @required GlobalKey<ScaffoldState> scaffoldKey,
  })  : _scaffoldKey = scaffoldKey,
        super(key: key);

  final double height;
  final GlobalKey<ScaffoldState> _scaffoldKey;

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
 TabController _controller;
  int  _activeTabIndex;

  @override
  void initState() {
    super.initState();

    _controller = TabController(vsync: this, length: 6);
    _controller.addListener(_setActiveTabIndex);

  }

  void _setActiveTabIndex() {
  _activeTabIndex = _controller.index;
}

  @override
  Widget build(BuildContext context) {
    final double height = MediaQuery.of(context).size.height;
    final double width = MediaQuery.of(context).size.width;
    return Container(
      height: widget.height,
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
             

 DefaultTabController(
              length: 3,
              child: Padding(
                padding: const EdgeInsets.only(left: 8.0, top: 15),
                child: Text(
                  'Brands',
                  style: TextStyle(
                      fontFamily: 'OpenSansLight',
                      fontSize: 30,
                      fontWeight: FontWeight.w400),
                ),
              ),
            ),
            new TabBar(
                controller: _controller,
                isScrollable: true,
                indicatorWeight: 0.01,
                unselectedLabelColor:
                    Theme.of(context).textTheme.headline1.color,
                unselectedLabelStyle: TextStyle(
                    color: Colors.black,
                    fontSize: 20,
                    fontFamily: 'OpenSansLight'),
                labelStyle: TextStyle(
                    color: Colors.deepPurple,
                    fontSize: 20,
                    fontWeight: FontWeight.w600,
                    fontFamily: 'OpenSansLight'),
                labelColor: Colors.deepPurple,
                tabs: <Widget>[
                  Tab(
                      child: Container(
                    height: 50,
                    width: 60,
                    child: Center(
                      child: Icon(ShoeCategory.sneakers),
                    ),
                    decoration: BoxDecoration(
                        color: Colors.white,
                        boxShadow: <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ],
                        borderRadius: BorderRadius.circular(20)),
                  )),
                  Tab(
                      child: Container(
                    height: 50,
                    width: 60,
                    child: Center(
                      child: Icon(ShoeCategory.sneakers),
                    ),
                    decoration: BoxDecoration(
                        color: Colors.white,
                        boxShadow: <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ],
                        borderRadius: BorderRadius.circular(20)),
                  )),
                  Tab(
                      child: Container(
                    height: 50,
                    width: 60,
                    child: Center(
                      child: Icon(ShoeCategory.sneakers),
                    ),
                    decoration: BoxDecoration(
                        color: Colors.white,
                        boxShadow: <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ],
                        borderRadius: BorderRadius.circular(20)),
                  )),
              
                
               
                ]),
            Container(
                height: 250,
                width: width,
                child: TabBarView(controller: _controller, children: [
                 //TAB1
                  Container(
                      child: ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 8,
                          shrinkWrap: false,
                          itemBuilder: (BuildContext context, int index) {
                            if (index == 7) {
                              return ViewMore(navigationRoute: ChooseKid());
                            }
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FeaturedCard(
                                  color1: Colors.lightBlue,
                                  color2: Colors.lightBlue[100],
                                  url:
                                      'https://i.dlpng.com/static/png/6838599_preview.png',
                                  index: random.nextInt(1000000)),
                            );
                          })),
                 //TAB 2
                  Container(
                      child: ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 8,
                          shrinkWrap: false,
                          itemBuilder: (BuildContext context, int index) {
                            if (index == 7) {
                              return ViewMore(navigationRoute: ChooseKid());
                            }
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FeaturedCard(
                                  color1: Colors.lightBlue,
                                  color2: Colors.lightBlue[100],
                                  url:
                                      'https://i.dlpng.com/static/png/6838599_preview.png',
                                  index: random.nextInt(1000000)),
                            );
                          })),
                 //TAB3
                  Container(
                      child: ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 8,
                          shrinkWrap: false,
                          itemBuilder: (BuildContext context, int index) {
                            if (index == 7) {
                              return ViewMore(navigationRoute: ChooseKid());
                            }
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FeaturedCard(
                                  color1: Colors.lightBlue,
                                  color2: Colors.lightBlue[100],
                                  url:
                                      'https://i.dlpng.com/static/png/6838599_preview.png',
                                  index: random.nextInt(1000000)),
                            );
                          })),
                 
                ]))

          ]))}

}

Upvotes: 1

Views: 1362

Answers (2)

Guillaume Roux
Guillaume Roux

Reputation: 7308

Here is a full example based on the code you provided. I simply added a var _selectedIndex which I set to the index of the current displayed tab. Each time you change your tab it will call a setState to update the value of _selectedIndex and refresh the UI so the selected element will have a different color and elevation.

Code

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(home: HomePage());
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  TabController _controller;

  int _selectedIndex = 0;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("asos", style: TextStyle(color: Colors.black)),
        elevation: 0,
        backgroundColor: Colors.white,
        bottom: TabBar(
          controller: _controller,
          isScrollable: true,
          indicatorWeight: 0.01,
          unselectedLabelColor: Theme.of(context).textTheme.headline1.color,
          labelColor: Colors.white,
          onTap: (index) => setState(() => _selectedIndex = index),
          tabs: List<Widget>.generate(
            _controller.length,
            (index) => Tab(
              child: Container(
                width: 60,
                alignment: Alignment.center,
                child: Icon(Icons.beach_access),
                decoration: BoxDecoration(
                  color: index == _selectedIndex ? Colors.orange : Colors.white,
                  boxShadow: index == _selectedIndex
                      ? <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ]
                      : [],
                  borderRadius: BorderRadius.circular(20),
                ),
              ),
            ),
          ),
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: List.generate(
          _controller.length,
          (index) => Container(
            alignment: Alignment.center,
            color: Colors.white,
            child: Text(
              "TAB $index",
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ),
      ),
    );
  }
}

Screenshot enter image description here

Upvotes: 2

norsparyt&#39;
norsparyt&#39;

Reputation: 3

i guess what you're simply trying to achieve is the selected tab decoration? In that case you can use the Tab Controller and use the index property to get the currently selected tab. You can then check the index to change the color/any other property.

colors: _tabController.index==1?Colors.amber:Colors.white;

inside the child property of your tabs

Upvotes: 0

Related Questions