TabBar icon color when tab is selected - flutter

I'm trying to change color of the tab icon when tab is selected. I know how to change the color of the icon, but I don't know how to make the color change when I select tab.
My code:
child: AppBar(
bottom: TabBar(
tabs: <Tab>[
Tab(
child: new Row(
children: <Widget>[
new Text("Select", textAlign: TextAlign.start),
new SizedBox(
width: 24.0,
),
new Icon(
Icons.arrow_drop_down,
color: Colors.blue.shade400,
),
],
....
)
)
]
)
)

To change the selected tab color, you just need to add this to TabBar :
labelColor: Colors.
unselectedLabelColor: Colors.white,
Full code:
DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
labelColor: Colors.deepOrange,
unselectedLabelColor: Colors.white,
tabs: <Tab>[
Tab(
child: Row(
children: <Widget>[
Text("Select", textAlign: TextAlign.start),
SizedBox(
width: 24.0,
),
Icon(
Icons.arrow_drop_down,
color: Colors.blue.shade400,
),
],
),
),
Tab(
child: Row(
children: <Widget>[
Text("Select", textAlign: TextAlign.start),
SizedBox(
width: 24.0,
),
Icon(
Icons.arrow_drop_down,
color: Colors.blue.shade400,
),
],
),
),
],
),
),
body: Center(
child: Container(
child: Text("This is a page blahblah"),
),
),
),
)
EDIT:
If u want to only change the icon color, then add color to Text and remove the color from the Icon in Tab, Code:
DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
labelColor: Colors.deepOrange,
unselectedLabelColor: Colors.white,
tabs: <Tab>[
Tab(
child: Row(
children: <Widget>[
Text("Select", textAlign: TextAlign.start, style: TextStyle(color: Colors.white),),
SizedBox(
width: 24.0,
),
Icon(
Icons.arrow_drop_down,
),
],
),
),
Tab(
child: Row(
children: <Widget>[
Text("Select", textAlign: TextAlign.start, style: TextStyle(color: Colors.white),),
SizedBox(
width: 24.0,
),
Icon(
Icons.arrow_drop_down,
),
],
),
),
],
),
),
body: Center(
child: Container(
child: Text("This is a page blahblah"),
),
),
),
)
EDIT #2
Now , This code changes the Icon color, but leaves the text color change as default (You can customize the change for color of text like the icon color). Code:
import 'package:flutter/material.dart';
class FirstPage extends StatefulWidget {
#override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
int _currentIndex = 0;
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
onTap: (index){
setState(() {
_currentIndex = index;
});
},
tabs: <Tab>[
Tab(
child: Row(
children: <Widget>[
Text("Select", textAlign: TextAlign.start,),
SizedBox(
width: 24.0,
),
Icon(
Icons.arrow_drop_down,
color: _currentIndex == 0 ? Colors.deepOrange : Colors.white54
),
],
),
),
Tab(
child: Row(
children: <Widget>[
Text("Select", textAlign: TextAlign.start,),
SizedBox(
width: 24.0,
),
Icon(
Icons.arrow_drop_down,
color: _currentIndex == 1 ? Colors.deepOrange : Colors.white54,
),
],
),
),
],
),
),
body: Center(
child: Container(
child: Text("This is a page blahblah"),
),
),
),
);
}
}

TabBar has the properties labelColor and unselectedLabelColor to set a selected/unselected color to any icon and text in the Tabs.
If you want to have a fixed color for icons or texts in the Tabs, you just have to specify that color in the Icon or Text in the Tab to override the color defined in the properties labelColor and unselectedLabelColor of the TabBar.
So, in your case, if you want to have a selected/unselected color for icons and a fixed color for the text, you have to set the labelColor and unselectedLabelColor in the TabBar with the colors for the icons and set a specific color on the text inside the Tabs.

Create a custom tab controller as shown click here
Do something like _tabController.index to get the index of the current tab.
For each tab check if its position(starting from 0) matches the TabController index and display the appropriate icon

Related

Place buttons tabs inside panel in SlidingUpPanel package flutter

How can I place some buttons to separate between tabs in a sliding up panel? Currently what I am trying to do is place them only when the slider is opened up, ohterwise the button tabs should dissapear. I am trying to controll this behavior with ternary operator and the variable:
PanelState == PanelState.OPEN ?
but it does not work for me. The row dissapear when I close the panel.
SlidingUpPanel(
body: Body()
backdropEnabled: true,
panelSnapping: true,
collapsed: ListTile(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
_pcBreedsGrouping.open();
},
child: const Text(
'Breeds',
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
InkWell(
onTap: () {
_pcBreedsGrouping.open();
},
child: const Icon(
Icons.arrow_drop_down,
color: Colors.black,
size: 30,
),
),
],
),
),
minHeight: MediaQuery.of(context).size.height * 0.08,
controller: _pcBreedsGrouping,
defaultPanelState: PanelState.CLOSED,
panel: Positioned(
child: Stack(
children: [
PanelState == PanelState.OPEN
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Breeds',
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
InkWell(
onTap: () => _pcBreedsGrouping.close(),
child: const Icon(
Icons.arrow_drop_up,
color: Colors.black,
size: 30,
),
),
],
)
: Container(),
Visually, the panel is like this right now and I drawed what I am trying in red:
When I close the panel I would like it to be how it is right now, without the buttons, but I do not know how to make them dissapear when is closed:
What I am trying to accomplish:

How to add a background colour to unselected label for a tabbar in flutter

I'm trying to design a tabbar with this pattern of design
But so I'm not able to make the unselected tab have a background just like this
When I try I end with something like this
Is it posible to use the Defaulttabbarcontroller to make this design or there is a way to design my own custom tab bar
This widget will provide you idea, I am using color.withOpacity, you may use colorFilter or others widget,
class TabBarDemo extends StatefulWidget {
const TabBarDemo({super.key});
#override
State<TabBarDemo> createState() => _TabBarDemoState();
}
class _TabBarDemoState extends State<TabBarDemo>
with SingleTickerProviderStateMixin {
late final TabController controller = TabController(length: 3, vsync: this)
..addListener(() {
setState(() {});
});
#override
Widget build(BuildContext context) {
final textStyle = TextStyle(color: Colors.blue.shade900);
return Scaffold(
backgroundColor: Colors.purple,
appBar: AppBar(
title: const Text('Tabs Demo'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
ActionChip(
backgroundColor: Colors.white,
shape: StadiumBorder(),
onPressed: () {
controller.animateTo(0);
},
label: Text(
"All",
style: controller.index == 0
? textStyle
: textStyle.copyWith(
color: textStyle.color!.withOpacity(.3),
),
),
),
SizedBox(width: 10),
ActionChip(
backgroundColor: Colors.white,
shape: StadiumBorder(),
onPressed: () {
controller.animateTo(1);
},
label: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(
Icons.ac_unit,
size: 12,
color: controller.index == 1
? Colors.red
: Colors.red.withOpacity(.4),
),
),
Text(
"Income",
style: controller.index == 1
? textStyle
: textStyle.copyWith(
color: textStyle.color!.withOpacity(.3),
),
),
],
),
),
SizedBox(
width: 10,
),
ActionChip(
backgroundColor: Colors.white,
shape: StadiumBorder(),
onPressed: () {
controller.animateTo(2);
},
label: Text(
"Expenses",
style: controller.index == 2
? textStyle
: textStyle.copyWith(
color: textStyle.color!.withOpacity(.3),
),
)),
],
),
Expanded(
child: TabBarView(
controller: controller,
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
),
),
],
),
),
);
}
}
Based on your case and design, I go with Chips and Wrap widgets if I want to build your design. Then I have a Container below them that acts as TabBarView. So, you need to change the child of the Container when the user taps on the Chip.
However, if you want to stick with TabBar then you need to set a theme when you launch the app. This is how I assign my themes, usually.

One tab using TabBarView contains multiple methods [Flutter]

What I want to do is to when pressed a movie tab it shows NowPlayedMovies() and BestMovies(), and when pressed tv shows tab to show NowPlayedTV() and BestTV(). At first I was using ListView but because I'm using tabs i need to use TabBarView. So in my child method I created 2 methods buildPage1 and buildPage2 in which I have put my 2 methods as mentioned above.
When I tried to run the code it displayed this error:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building _TabControllerScope:
The getter 'key' was called on null.
Receiver: null
Tried calling: key
The relevant error-causing widget was:
DefaultTabController
Here is my code:
class HomePageMovie extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePageMovie> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF151C26),
appBar: AppBar(
backgroundColor: Color(0xFF151C26),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
logo,
height: 195,
),
],
),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
EvaIcons.searchOutline,
color: Colors.white,
))
],
titleSpacing: 0.0,
bottom: PreferredSize(
preferredSize: Size.fromHeight(75.0),
child: DefaultTabController(
length: 2,
child: TabBar(
indicatorColor: Color(0xFFf4C10F),
indicatorWeight: 4.0,
unselectedLabelColor: Colors.white,
labelColor: Colors.white,
tabs: [
Tab(
icon: Icon(Icons.movie),
child: Text(
"Movies",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
),
Tab(
icon: Icon(Icons.live_tv),
child: Text(
"TV Shows",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
)
]),
),
),
),
body: DefaultTabController(
length: 2,
child: TabBarView(
children: [buildPage1(), buildPage2()],
),
));
}
buildPage1() {
NowPlayingMovies();
BestMovie();
}
buildPage2() {
NowPlayingTV();
BestTV();
}
}
Here is visual representation of what I'm trying to achieve:
Any help would be great. Thanks in advance :)
Use only one DefaultTabBarController at the top of your widget tree (in this case, as a parent of your Scaffold and remove the other two).
You should only use a single DefaultTabBarController that is shared between the TabBar and the TabBarView.
So with help of Miguel what I did wrong was I didn't put a specific controller to connect these 2, in my case as a solution I wrapped them both in common default controller. As of the 2nd part of the problem what I did is simply put ListView to display these 2
The code of solution:
class _HomePageState extends State<HomePageMovie> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
backgroundColor: Color(0xFF151C26),
appBar: AppBar(
backgroundColor: Color(0xFF151C26),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
logo,
height: 195,
),
],
),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
EvaIcons.searchOutline,
color: Colors.white,
))
],
titleSpacing: 0.0,
bottom: PreferredSize(
preferredSize: Size.fromHeight(75.0),
child: TabBar(
indicatorColor: Color(0xFFf4C10F),
indicatorWeight: 4.0,
unselectedLabelColor: Colors.white,
labelColor: Colors.white,
tabs: [
Tab(
icon: Icon(Icons.movie),
child: Text(
"Movies",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
),
Tab(
icon: Icon(Icons.live_tv),
child: Text(
"TV Shows",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
)
]),
),
),
body: TabBarView(
children: [
ListView(
children: <Widget>[NowPlayingMovies(), BestMovie()],
),
ListView(
children: <Widget>[
NowPlayingTV(),
BestTV(),
],
),
],
),
),
);
}
}

How to create a tab bar at center of the screen in flutter?

I'm trying to create a tab bar at the center of the screen using flutter while trying it I gave TabBarView in a column and I was stuck in this error. Please resolve this.
I/flutter ( 3983): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 3983): The following assertion was thrown during performResize():
I/flutter ( 3983): Horizontal viewport was given unbounded height.
I/flutter ( 3983): Viewports expand in the cross axis to fill their container and constrain their children to match
I/flutter ( 3983): their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of
I/flutter ( 3983): vertical space in which to expand.
The source code is
class profilePage extends StatefulWidget {
#override
profilePageState createState() => profilePageState();
}
class profilePageState extends State<profilePage>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
_tabController = new TabController(length: 2, vsync: this);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
Container(
child: Column(crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 40,
),DefaultTabController(
length: 2,
child: Column(children: [TabBar(
unselectedLabelColor: Colors.black,
labelColor: Colors.red,
tabs: <Widget>[
Tab(
icon: Icon(Icons.people),
),
Tab(
icon: Icon(Icons.person),
)
],controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
),TabBarView(
children: <Widget>[Text('people'), Text('Person')],
controller: _tabController,
),
]),
),
],
),
),
],
),
);
}
}
You can see the above model of the image what I'm trying to achieve. I've tried many things but I've stuck here.
How to rectify this error and how to create a tab bar at the center of my screen?
I added a demo of what you are trying to get (I followed the Image you posted):
NOTE : I had to make few changes to the way you arranged your widget tree.
class profilePage extends StatefulWidget {
#override
profilePageState createState() => profilePageState();
}
class profilePageState extends State<profilePage> {
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text(
'My Profile',
),
centerTitle: true,
backgroundColor: Colors.grey[700].withOpacity(0.4),
elevation: 0,
// give the app bar rounded corners
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0),
),
),
leading: Icon(
Icons.menu,
),
),
body: Column(
children: <Widget>[
// construct the profile details widget here
SizedBox(
height: 180,
child: Center(
child: Text(
'Profile Details Goes here',
),
),
),
// the tab bar with two items
SizedBox(
height: 50,
child: AppBar(
bottom: TabBar(
tabs: [
Tab(
icon: Icon(Icons.directions_bike),
),
Tab(
icon: Icon(
Icons.directions_car,
),
),
],
),
),
),
// create widgets for each tab bar here
Expanded(
child: TabBarView(
children: [
// first tab bar view widget
Container(
color: Colors.red,
child: Center(
child: Text(
'Bike',
),
),
),
// second tab bar viiew widget
Container(
color: Colors.pink,
child: Center(
child: Text(
'Car',
),
),
),
],
),
),
],
),
),
);
}
}
OUTPUT:
To put the TabBar at the center of the screen, your Profile Container's height should be the screen height divided by 2
Like this
class profilePage extends StatefulWidget {
#override
profilePageState createState() => profilePageState();
}
class profilePageState extends State<profilePage>
with SingleTickerProviderStateMixin {
TabController _tabController;
#override
void initState() {
_tabController = new TabController(length: 2, vsync: this);
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: MediaQuery.of(context).size.height /2,
child: Center(child: Text("Profile"),),
color: Colors.blue,
),
TabBar(
unselectedLabelColor: Colors.black,
labelColor: Colors.red,
tabs: [
Tab(
icon: Icon(Icons.people),
),
Tab(
icon: Icon(Icons.person),
)
],
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
),
Expanded(
child: TabBarView(
children: [Text('people'), Text('Person')],
controller: _tabController,
),
),
],
),
),
);
}
}
Result:
Also can try this,
AppBar(
leading: IconButton(
constraints: BoxConstraints(),
padding: EdgeInsets.zero,
icon: Container(
padding: EdgeInsets.fromLTRB(10, 5, 0, 5),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(20)),
// color: MyColors.primaryColorLight.withAlpha(20),
color: Colors.white,
),
child: Icon(
Icons.arrow_back_ios,
color: kPrimaryColor,
// size: 16,
),
),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: kPrimaryColor,
toolbarHeight: 80,
elevation: 5.0,
title: TabBar(//Add tab bar to title
indicator: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(30)),
color: Colors.white),
labelColor: kPrimaryColor,
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.label,
isScrollable: true,
tabs: [
Container(
height: 30.0,
width: 100,
child: Tab(
child: Align(
alignment: Alignment.center,
child: Text(
"Ongoing",
style: TextStyle(fontSize: 16),
),
),
),
),
Container(
width: 100,
height: 30.0,
child: Tab(
child: Align(
alignment: Alignment.center,
child: Text(
"Requests",
style: TextStyle(fontSize: 16),
),
),
),
),
],
),
)

Flutter positioned widget cuts off content

I'm attempting to create a notification widget with a number overlay.
I've followed the code here to make the widget.
Using this code (not specifying a position), produces the following widget:
Widget iconWidget() {
return Stack(
children: <Widget>[
Center(
child: Container(
child: Icon(
icon,
color: color,
),
)),
Positioned(
child: CircleAvatar(
child: Text('$count',
style: TextStyle(fontSize: 12, color: Colors.white)),
backgroundColor: count == 0 ? Colors.grey : Colors.black,
),
)
],
);
}
However, as soon as I specify a position (right: 0), my widget gets gut off:
Widget iconWidget() {
return Stack(
children: <Widget>[
Center(
child: Container(
child: Icon(
icon,
color: color,
),
)),
Positioned(
right: 0,
child: CircleAvatar(
child: Text('$count',
style: TextStyle(fontSize: 12, color: Colors.white)),
backgroundColor: count == 0 ? Colors.grey : Colors.black,
),
)
],
);
}
My widget is being created as an icon within a tab controller:
Tab(
icon: IconWithCount(
icon: FlutterIcons.heartbeat_faw5s,
color: Colors.red,
count: 5)
.iconWidget(),
),
Full class creating the widget:
class IconWithCount {
final IconData icon;
final int count;
final Color color;
IconWithCount({
this.icon,
this.count,
this.color,
});
Widget iconWidget() {
return Stack(
children: <Widget>[
Center(
child: Container(
child: Icon(
icon,
color: color,
),
)),
Positioned(
right: 0,
child: CircleAvatar(
child: Text('$count',
style: TextStyle(fontSize: 12, color: Colors.white)),
backgroundColor: count == 0 ? Colors.grey : Colors.black,
),
)
],
);
}
}
overflow is Deprecated. Use this:
Stack(
clipBehavior: Clip.none, // <---
children: [],
)
Inside the stack , just add this
overflow: Overflow.visible,