Reputation: 81
I am trying to design my tabs as the design below:
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
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),
),
),
),
),
);
}
}
Upvotes: 2
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