Flutter TabBar wrong labelColor when use ThemeData - flutter

I try to change labelColor value for TabBar via ThemeData.
child: MaterialApp(
theme: ThemeData.light().copyWith(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.deepPurple,
).copyWith(
secondary: Colors.amber,
),
tabBarTheme: ThemeData.light().tabBarTheme.copyWith(
labelColor: ThemeData.light().colorScheme.secondary,
),
),
home: const RootContainer(),),);
So my tabs should have shade of amber color. Instead they are some blue ... (picture below).
What I'm doing wrong and how to fix it ?
Result:

The color doesn't change because the ThemeData.light() returns ThemeData that is not initilized.
For using the color of the theme, wrap your widget by Builder with Theme.of(context) like below.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light().copyWith(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.deepPurple,
).copyWith(
secondary: Colors.amber,
),
),
home: Builder(builder: (context) {
final theme = Theme.of(context);
return Theme(
data: theme.copyWith(
tabBarTheme: theme.tabBarTheme.copyWith(
labelColor: theme.colorScheme.secondary,
),
),
child: const RootContainer(),
);
}),
);
}
}

Related

Widget not updating its colorScheme with global ThemeData

The app app here loads a tabbed simple app with a scaffold, app bar, and bottomNavigationBar which is set as a TabBar.
When set at the bottomNavigationBar, the TabBar becomes white so I've overridden its background color using a Container widget.
While the rest of my app will change its color palette as expected, however it doesn't for my TabBar. Using Theme.of(context) to get the primary color doesn't work either, as the Theme's color scheme doesn't seem to change at all.
I've attached pictures of the problem too.
theme: ThemeData.light()
theme: ThemeData.dark()
Notice how the whole app except the bottom TabBar reflects these changes happily.
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sereal',
theme: ThemeData(primarySwatch: Colors.indigo),
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('App'),
),
bottomNavigationBar: Container(
color: Theme.of(context).primaryColor,
child: const TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.calendar_today),
text: 'Planner',
),
Tab(
icon: Icon(Icons.amp_stories),
text: 'Cards',
),
Tab(
icon: Icon(Icons.auto_stories),
text: 'Notes',
),
],
),
),
body: const TabBarView(
children: <Widget>[CardsView(), NotesView(), PlannerView()],
)),
));
}
}
1: make the DefaultTabController in a separate widget.
2: add these properties to the MaterialApp widget:
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.indigo,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.indigo,
),
themeMode: ThemeMode.light,
3: instead of wraping the TabBar with a Container, wrap it with a Material widget
this is the main file code :
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.indigo,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.indigo,
),
themeMode: ThemeMode.light,
home: const HomePage(),
);
}
}
this is the homepage code:
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('App'),
),
bottomNavigationBar: Material(
color : Theme.of(context).primaryColor,
child: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.calendar_today),
text: 'Planner',
),
Tab(
icon: Icon(Icons.amp_stories),
text: 'Cards',
),
Tab(
icon: Icon(Icons.auto_stories),
text: 'Notes',
),
],
),
),
body: const TabBarView(
children: <Widget>[CardsView(), NotesView(),PlannerView()],
)),
);
}
}
.................
this is how it looks when you run the app:
and this is how it looks when you change the themeMode to: ThemeMode.dark

Flutter ThemeData Primary color not changing from theme when trying to add a primary color

Im following the BMI Calculator app from the London App Brewery on LinkedIn Learning.
when attempting to set the primaryColor to red, my emulator still shows the Light Blue default AppBar even though i am overriding the Primary Color. here's the code
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.red,
),
home: const InputPage(),
);
}
}
class InputPage extends StatefulWidget {
const InputPage({Key? key}) : super(key: key);
#override
_InputPageState createState() => _InputPageState();
}
class _InputPageState extends State<InputPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BMI CALCULATOR'),
),
body: const Center(
child: Text('Body Text'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
}
}
Use primarySwatch
theme: ThemeData(
primarySwatch: Colors.red,
),
I am also attending same training from LondonAppBrewery. This code fixed the problem.
Widget build(BuildContext context) {
return MaterialApp(
title: "BMI Calculator",
debugShowCheckedModeBanner: false,
theme: ThemeData.dark().copyWith(
appBarTheme:AppBarTheme(
backgroundColor: Color(0xff0a0e21),
),
scaffoldBackgroundColor: Color(0xff0a0e21),
),
home: InputPage(),
);
This issue has been pointed at flutter github page. They say
We will eventually be moving all components away from ThemeData.primaryColor
So you can use
theme: ThemeData(
colorScheme: ColorScheme.light().copyWith(primary: Colors.red),
);
Using the following approach you can have full control over the individual properties in Themedata
class BMICalculator extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.pink,
appBarTheme: AppBarTheme(
backgroundColor: Colors.orangeAccent,
),
),
home: InputPage(),
);
}
}
I'm undergoing the same training program. As Mohtashim mentioned above, I tried to tweak the background app theme code and it worked as expected.
theme: ThemeData(
primarySwatch: Colors.pink,
appBarTheme: AppBarTheme(
backgroundColor: Color(0xFF101427), //use your hex code here
),
)
I also figured out just like you guys answered above. However, in dark design there was a shadowColor missing, so I added it.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFF0a0e21),
elevation: 5.0,
shadowColor: Colors.black87,
),
primaryColor: const Color(0xFF0A0E21),
colorScheme: ColorScheme.fromSwatch().copyWith(
secondary: const Color(0xFF101427),
),
scaffoldBackgroundColor: const Color(0xFF0A0E21),
),
home: const MainPage(),
);
}
}
If you want to add default colors that provide by flutter you can change like this.
theme: ThemeData(
primaryColor: Colors.red,
primarySwatch: Colors.red,
),
If you want to use custom colors, you can use like this
static const Color primaryColor = Color(0xFF623CEA);
static MaterialColor primaryColorSwatch = MaterialColor(
primaryColor.value,
const <int, Color>{
50: Color(0xFF623CEA),
100: Color(0xFF623CEA),
200: Color(0xFF623CEA),
300: Color(0xFF623CEA),
400: Color(0xFF623CEA),
500: Color(0xFF623CEA),
600: Color(0xFF623CEA),
700: Color(0xFF623CEA),
800: Color(0xFF623CEA),
900: Color(0xFF623CEA),
},
);
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: primaryColor,
primarySwatch: primaryColorSwatch,
),
home: Demo(),
);
theme: ThemeData.dark().copyWith(
colorScheme: ColorScheme.light(
primary: Color(0xFF0A0E21),
),
scaffoldBackgroundColor: Color(0xFF0A0D22),
),
U can Use :
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.red,
)
)
Try this code for changing app bar color worked for me,replace the color code as per ur need
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: Colors.red,
appBarTheme: AppBarTheme(
backgroundColor: Color(0xFF0A0E21),
),
accentColor: Colors.purple,
),
home: InputPage(),
);
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.light()
.copyWith(primary: Colors.red, secondary: Colors.red))),
home: InputPage(),
);
}
This worked for me.
class BMICalculator extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(appBarTheme: AppBarTheme(color: Color(0xff0a0e21))),
home: InputPage(),
);
}
}
So for hex color, we need to use MaterialColor() of primarySwatch. And for Material color, there are two arguments required, hex color and Map data for the shades of the color.
First create a Map variable, color, outside the stateless widget:
Map<int, Color> color =
{
50:Color.fromRGBO(136,14,79, .1),
100:Color.fromRGBO(136,14,79, .2),
200:Color.fromRGBO(136,14,79, .3),
300:Color.fromRGBO(136,14,79, .4),
400:Color.fromRGBO(136,14,79, .5),
500:Color.fromRGBO(136,14,79, .6),
600:Color.fromRGBO(136,14,79, .7),
700:Color.fromRGBO(136,14,79, .8),
800:Color.fromRGBO(136,14,79, .9),
900:Color.fromRGBO(136,14,79, 1),
};
And then:
primarySwatch: MaterialColor(0xFF0A0E21,color),
This will work.
The most complete way to do it would be to set the colorScheme property inside ThemeData().
In the ColorScheme class itself you can either decide to set manually all of the color groups, like so:
theme: ThemeData(
colorScheme: ColorScheme(
brightness: Brightness.light,
primary: Colors.red,
onPrimary: Colors.white,
secondary: Colors.green,
onSecondary: Colors.white,
error: Colors.yellow,
onError: Colors.black,
background: Colors.white,
onBackground: Colors.black,
surface: Colors.grey,
onSurface: Colors.black,
),
),
Or you can decide to use the ColorScheme.fromSwatch() constructor to create a swatch:
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.green,
accentColor: Colors.amber,
),
),
I follow the same course. This is the code that helped me. Also thank you guys for answering the questions above. I nearly pulled out my hair. If anyone knows why flutter changes and deprecates syntax so dramatically please explain. It would be nice to know.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
appBarTheme: AppBarTheme(
backgroundColor: Color(0xff0a0e21),
),
primaryColor: Color(0xFF0A0E21),
scaffoldBackgroundColor: Color(0xFF0A0E21),
colorScheme: ColorScheme.fromSwatch().copyWith(
secondary: Colors.purple,
),
),
home: InputPage(),
);
}
}

how to change theme data in flutter?

class _NavigationBarState extends State<NavigationBar> {
int _currentIndex = 0;
final List<Widget> tabs = [
CustomerAccountPage(),
HomePage(),
AppInforamtionPage(),
CategoriesPage(),
];
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light().copyWith(
primaryColor: Colors.amber,
accentColor: Colors.black
),
debugShowCheckedModeBanner: false,
home: Scaffold(
bottomNavigationBar: BottomNavigationBar(
showUnselectedLabels: true,
unselectedItemColor: Theme.of(context).primaryColor,
selectedItemColor: Theme.of(context).accentColor,
currentIndex: _currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text("account"),
),
BottomNavigationBarItem(
icon: Icon(Icons.play_for_work),
title: Text("shop"),
),
BottomNavigationBarItem(
icon: Icon(Icons.all_out),
title: Text("more info "),
),
BottomNavigationBarItem(
icon: Icon(Icons.all_out),
title: Text(" categories"),
),
],
onTap: (index) {
setState(() {
_currentIndex = index;
});
}),
),
centerTitle: true,
backgroundColor: Colors.white,
),
body: tabs[_currentIndex],
floatingActionButton: FloatingActionButton(onPressed: null, backgroundColor: Theme.of(context).primaryColor,),
),
);
}
}
I'm using flutter , and trying to set the theme data, but it doesn't work.
I tried to change the theme in this way, but I can't see the result in my app, I don't know what is the problem, can anyone help me!
stackoverflow want from me to explain more, but I haven't anything else to explain, thanks in advance!
The context used in Theme.of(context).primaryColor is not the right context. You need to put the MaterialApp in another widget wrapping the current widget, e.g.,
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData.light()
.copyWith(primaryColor: Colors.amber, accentColor: Colors.black),
home: NavigationBar(),
);
}
}
And the build method of the _NavigationBarState:
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
showUnselectedLabels: true,
unselectedItemColor: Theme.of(context).primaryColor,
selectedItemColor: Theme.of(context).accentColor,
...
After trying very hard to understand Material Design, I found the following solution which is easy and clean. Here is my complete code.
color_scheme.dart
import 'package:flutter/material.dart';
const lightColorScheme = ColorScheme(
brightness: Brightness.light,
primary: Color(0xFF687DAF),
onPrimary: Color(0xFFFFFFFF),
secondary: Color(0xFFf37b67),
onSecondary: Color(0xFFFFFFFF),
error: Color(0xFFBA1A1A),
onError: Color(0xFFFFFFFF),
background: Color(0xFFFEFFFF),
onBackground: Color(0xFF3b3b3b),
surface: Color(0xFFFEFFFF),
onSurface: Color(0xFF3b3b3b),
);
const darkColorScheme = ColorScheme(
brightness: Brightness.dark,
primary: Color(0xFFADC6FF),
onPrimary: Color(0xFF002E69),
secondary: Color(0xFFBBC6E4),
onSecondary: Color(0xFF253048),
error: Color(0xFFFFB4AB),
onError: Color(0xFF690005),
background: Color(0xFF1B1B1F),
onBackground: Color(0xFFE3E2E6),
surface: Color(0xFF1B1B1F),
onSurface: Color(0xFFE3E2E6),
);
theme.dart
import 'package:first_project/shared/color_schemes.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
final ThemeData lightThemeDataCustom = _buildLightTheme();
ThemeData _buildLightTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
colorScheme: lightColorScheme,
primaryColor: lightColorScheme.primary,
scaffoldBackgroundColor: lightColorScheme.background,
textTheme: GoogleFonts.montserratTextTheme(ThemeData.light().textTheme),
);
}
final ThemeData darkThemeDataCustom = _buildDarkTheme();
ThemeData _buildDarkTheme() {
final ThemeData base = ThemeData.dark();
return base.copyWith(
colorScheme: darkColorScheme,
primaryColor: darkColorScheme.primary,
scaffoldBackgroundColor: darkColorScheme.background,
textTheme: GoogleFonts.montserratTextTheme(ThemeData.dark().textTheme),
);
}
main.dart
import 'package:first_project/shared/theme_two.dart';
import 'package:flutter/services.dart';
import '../screens/bottom_bar.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark));
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: lightThemeDataCustom,
darkTheme: darkThemeDataCustom,
home: const BottomBar(),
);
}
}
If you follow this approach, then you don't need to define colors in each and every widget. Just change the color scheme, flutter will automatically change colors according to Light theme and Dark theme.
I do not add textTheme customization code but you can do it in theme.dart file.
Hope this will help someone.

Unable to override ThemeData

I want to have a different background color in MenuPage. I'm trying to override the themeData - I've followed the themeData tutorial from official flutter page but unable to get the result. do you guys have any suggestion?
void main() => runApp(MyApp());
final ThemeData _themeData = new ThemeData( // app theme
scaffoldBackgroundColor: darkNavy,
canvasColor: lightNavy,
accentColor: lightNavy,
primarySwatch: Colors.grey,
appBarTheme: AppBarTheme(
color: darkNavy,
brightness: Brightness.dark,
elevation: 10,
iconTheme: IconThemeData(
color: lightGrey,
),
textTheme: TextTheme(
headline6: GoogleFonts.crimsonPro(
color: darkGrey,
fontSize: 20,
fontWeight: FontWeight.w400))),
);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: _themeData,
home: HomeScreen(),
);
}
}
class MenuDashBoard extends StatefulWidget {
#override
_MenuDashBoardState createState() => _MenuDashBoardState();
}
class _MenuDashBoardState extends State<MenuDashBoard> {
#override
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
canvasColor: lightNavy,
scaffoldBackgroundColor: lightNavy
),
child: Scaffold(
body: Container(
padding: EdgeInsets.only(top: 30, bottom: 30, left: 20),
child: Column(
My main homeScreen has a dark navy background i want to have a light navy in my Menu page.
You can use the attribute 'scaffoldBackgroundColor' in theme data, setting to the color you want With this, if you are using the scaffold widget, your background app will have the color you want. See:
MaterialApp(
title: 'App',
theme: ThemeData(
scaffoldBackgroundColor: Colors.blue,
),
home: YourScreen()
),

Declaring one or more custom Themes

I'm trying to create a custom theme inside a flutter project.
I've created a separate file (mycolors.dart) where i defined some colors (const myPrimaryColor = const Color(0xFFFF3900); etc etc)
Then, in main.dart i'm referring to these colors and a custom font but inside the Widget build...
How can I isolate the theme data (colors and font/text styles), let's say "separately", and to refer to it inside the class?
Can I also define 2 different themes and use them later in the project?
Many thanks.
import 'package:flutter/material.dart';
import 'package:my_repository/mycolors.dart';
import 'package:flutter_statusbarcolor/flutter_statusbarcolor.dart';
void main() {
runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
FlutterStatusbarcolor.setStatusBarColor(myPrimaryColor);
return MaterialApp(
theme: ThemeData(
fontFamily: 'Raleway',
primaryColor: myPrimaryColor,
accentColor: myAccentColor,
scaffoldBackgroundColor: myBackgroundColor,
cardColor: mySurfaceColor,
textSelectionColor: myPrimaryColor,
errorColor: myErrorColor,
),
home: Scaffold( ....
You can define your themes in a class and then call ThemeName().theme.
here is how I have a theme file in my app:
class MuskTheme {
...
ThemeData get theme => ThemeData(
brightness: Brightness.dark,
primarySwatch: musk,
accentColor: accentColor,
fontFamily: fontFamily,
backgroundColor: musk,
canvasColor:canvasColor,
textTheme: _textTheme,
iconTheme: _iconTheme,
cardColor: Color(0xff313A49),
appBarTheme: AppBarTheme(color: canvasColor,elevation: 0),
dialogBackgroundColor: canvasColor,
snackBarTheme: SnackBarThemeData(
backgroundColor: musk[800],
actionTextColor: accentColor,
),
);
...
}
for changing your theme during runtime you need to rebuild the MaterialApp widget by implementing a stateful widget that is higher than MaterialApp and can rebuild it upon request.
example implementation:
class ThemeChanger extends StatefulWidget {
final ThemeData initialTheme;
final MaterialApp Function(BuildContext context, ThemeData theme)
materialAppBuilder;
const ThemeChanger({Key key, this.initialTheme, this.materialAppBuilder})
: super(key: key);
#override
_ThemeChangerState createState() => _ThemeChangerState();
static void setTheme(BuildContext context, ThemeData theme) {
var state = context.ancestorStateOfType(TypeMatcher<_ThemeChangerState>())
as _ThemeChangerState;
state.setState(() {
state.theme = theme;
});
}
}
class _ThemeChangerState extends State<ThemeChanger> {
ThemeData theme;
#override
void initState() {
super.initState();
theme = widget.initialTheme;
}
#override
Widget build(BuildContext context) {
return widget.materialAppBuilder(context, theme);
}
}
then you'll need to build your MaterialApp with it:
class ThemeChangingApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ThemeChanger(
initialTheme: ThemeData(
primarySwatch: Colors.blue,
),
materialAppBuilder: (context, theme) {
return MaterialApp(
theme: theme,
home: StartingPage(),
);
},
);
}
}
and in your app you can change the theme like this:
class StartingPage extends StatefulWidget {
#override
_StartingPageState createState() => _StartingPageState();
}
class _StartingPageState extends State<StartingPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
child: Center(
child: FlatButton(
child: Text('change theme to orange'),
onPressed: () {
ThemeChanger.setTheme(
context,
ThemeData(
primarySwatch: Colors.orange,
));
},
),
),
),
);
}
}
this package does a similar thing.
You can build a scaffold with a different theme just by warpping it with a Theme widget:
class StartingPage extends StatefulWidget {
#override
_StartingPageState createState() => _StartingPageState();
}
class _StartingPageState extends State<StartingPage> {
#override
Widget build(BuildContext context) {
return Theme(
data: ThemeData.dark(),
child: Scaffold(
appBar: AppBar(),
body: Container(
child: Center(
child: Text('test'),
),
),
),
);
}
}
final ThemeData customTheme = _buildcustomTheme();
ThemeData _buildcustomTheme() {
return customThemeFoundation;
}
ThemeData customThemeFoundation =ThemeData(
brightness: Brightness.dark,
primaryColor: Color.fromRGBO(40, 204, 86, 1),
accentColor: Colors.cyan[600],
fontFamily: 'Georgia',
textTheme: TextTheme(
headline1: TextStyle(fontSize: 72.0, fontWeight: FontWeight.bold),
headline6: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
bodyText2: TextStyle(fontSize: 14.0, fontFamily: 'Hind'),
),
and in main.dart just call it by
import 'theme.dart';
and just relpace theme:{.....} with theme: customTheme,