Widget not updating its colorScheme with global ThemeData - flutter

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

Related

How to change theme to dark on click on IconButton?

In my application, in the appBar, there is a button that should change the theme to dark. I need to create functionality Provider. How can this be implemented? I just need to change the Scaffold color to black and the text color to white.
My main.dart:
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: const TextTheme(
headline1: TextStyle(fontSize: 50.0, fontWeight: FontWeight.bold),
headline5: TextStyle(fontSize: 36.0, fontStyle: FontStyle.italic),
subtitle2: TextStyle(fontSize: 10.0, color: Colors.black),
bodyText1: TextStyle(fontSize: 14.0, color: Colors.black),
),
),
home: const HomeScreen(),
);
}
My switch button:
appBar: AppBar(
title: const Text('Flutter theme config'),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
},
icon: const Icon(Icons.dark_mode),
)
],
),
Theme provider:
class ThemeProvider extends ChangeNotifier {
}
You can try something like this :
First we provide our Provider globally for the whole application, and then in the attribute theme: we listen for the change.
** main **
void main() async {
runApp(
MultiProvider( // create the provider
providers: [
ChangeNotifierProvider(
create: (_) => ThemeProvider(),
)
],
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Material App',
initialRoute: HomeScreen.routerName,
routes: {
},
theme: Provider.of<ThemeProvider>(context).currentTheme, // listen to the current theme
);
}
}
In the provider we will only have two functions, one to switch to LightMode and the other to DarkMode, then we add it to the currentTheme variable which is the one that listens in the main
** ThemeProvider **
class ThemeProvider extends ChangeNotifier {
ThemeData? currentTheme;
setLightMode() {
currentTheme = ThemeData(
brightness: Brightness.light, // LightMode
scaffoldBackgroundColor: Colors.red,
[...] // more attributes
);
notifyListeners();
}
setDarkmode() {
currentTheme = ThemeData(
brightness: Brightness.dark, // DarkMode
scaffoldBackgroundColor: Colors.green,
[...] // more attributes
);
notifyListeners();
}
}
Finally we create a StatefulWidget to change the isDarkMode variable to call the provider
** Button Home **
class _HomeScreenState extends State<SettingsScreen> {
bool isDarkmode = false; // new variable
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Settings"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
onPressed: () {
final themeProvider =
Provider.of<ThemeProvider>(context, listen: false); // get the provider, listen false is necessary cause is in a function
setState(() {
isDarkmode = !isDarkmode;
}); // change the variable
isDarkmode // call the functions
? themeProvider.setDarkmode()
: themeProvider.setLightMode();
},
icon: const Icon(Icons.dark_mode),
),
),
);
}
}

Flutter TabBar wrong labelColor when use ThemeData

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(),
);
}),
);
}
}

In flutter How to change FAB (Floating Action Button) custom animation Icon

I am new in flutter and now i am stuck to change FAB animation.Actually i am trying to before i press FAB that time it hadd add Icon and after press FAB it change icon close insted of add icon.
i provide one animation gif file link to more understand if any one know the solution please suggest me to solve this problem.
Here is the link https://miro.medium.com/max/468/1*qGa6VU4grjqEwAOScRm9BA.gif
In this link provided animation is showing that before press it shows the menu option icon and after press it show close icon but i want add option instead of menu option.
like add_close not a menu_close animationIcon.
I hope you understand my problem and suggest me
I think this code fulfill your requirements.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter FAB Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("FAB"),
),
floatingActionButton: AnimatedIconButton(
size: 30,
onPressed: () {
},
duration: Duration(milliseconds: 200),
endIcon: Icon(
Icons.close,
color: Colors.white,
),
startIcon: Icon(
Icons.add,
color: Colors.white,
),
startBackgroundColor: Colors.blue,
endBackgroundColor: Colors.blue,
),
);
}
}
this is the namespace which i used:
import 'package:flutter/material.dart';
import 'package:animated_icon_button/animated_icon_button.dart';
This code will work for all your requirements such as animation,multiple fab buttons with on pressed and also support images as a fab icon.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter FAB Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: UniWidget(),
);
}
}
class UniWidget extends StatefulWidget {
#override
_UniWidgetState createState() => _UniWidgetState();
}
class _UniWidgetState extends State<UniWidget> {
#override
Widget build(BuildContext context) {
var childButtons = List<UnicornButton>();
childButtons.add(UnicornButton(
hasLabel: false,
currentButton: FloatingActionButton(
backgroundColor: Colors.blue,
mini: false,
child: Padding(
padding: const EdgeInsets.all(15),
child: Image.asset('assets/images/arrow.png'),
),
onPressed: () {
print('scanbar');
},
)));
childButtons.add(UnicornButton(
hasLabel: false,
currentButton: FloatingActionButton(
backgroundColor: Colors.blue,
mini: false,
child: Padding(
padding: const EdgeInsets.all(15),
child: Image.asset('assets/images/contact.png'),
),
onPressed: () {
print('Contact');
},
)));
return Scaffold(
floatingActionButton: UnicornDialer(
parentButtonBackground: Colors.blue,
orientation: UnicornOrientation.VERTICAL,
childPadding: 10.0,
parentButton: Icon(Icons.add),
childButtons: childButtons),
appBar: AppBar(
title: Text("Fab demo"),
),
body: Center());
}
}
here is the namespaces
import 'package:flutter/material.dart';
import 'package:unicorndial/unicorndial.dart';
I hope it will fulfill your all type of requirements and work well in your project.

Flutter How to force Dark mode on specific screens

I'm building a news app using flutter, the app has 2 theme modes already dark and light debends on phone settings and works really great, but I need on some screens on my app to be dark whatever such as videos section or video page ...etc
I googled this and all the results about the normal theming which I did already.
I don't think there's any code I can put here to help, but if there please let me know!
You can override the current theme at any time simply by placing the desired widget in a Theme class.
I don't know if you are using Scaffold or not, but let's say you are then all you would need to do is:
// declare theme data if you don't have it already
final ThemeData specialThemeData = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.yellow[700],
// and so on...
);
#override
Widget build(BuildContext context) {
// this the point of interest, return a Theme with desired Theme Data
return Theme(
data: specialThemeData,
child: Scaffold(
//...
It doesn't have to be Scaffold, it will work on any widegt.
Here is a fully functional example you can try out yourself:
import 'package:flutter/material.dart';
final ThemeData specialThemeData = ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.yellow[700],
accentColor: Colors.orange[500],
textTheme: TextTheme(
headline1: TextStyle(fontSize: 48.0, fontWeight: FontWeight.bold),
headline6: TextStyle(fontSize: 24.0, fontStyle: FontStyle.italic),
bodyText2: TextStyle(fontSize: 18.0),
),
);
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Home Page default theme'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void _goToSpecialPage() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MySpecialPage()
)
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Your homepage, using default theme.',),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _goToSpecialPage,
tooltip: 'Go to special page',
child: Icon(Icons.navigate_next),
),
);
}
}
class MySpecialPage extends StatefulWidget {
MySpecialPage({Key key}) : super(key: key);
#override
_MySpecialPageState createState() => _MySpecialPageState();
}
class _MySpecialPageState extends State<MySpecialPage> {
void _backToHomePage(){
Navigator.pop(context);
}
#override
Widget build(BuildContext context) {
// this the point of interest, return a Theme with desired Theme Data
return Theme(
data: specialThemeData,
child: Scaffold(
appBar: AppBar(
title: Text('Special theme page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Your special page that uses a different theme.',),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _backToHomePage,
tooltip: 'Go back to home page',
child: Icon(Icons.navigate_before),
),
),
);
}
}

Flutter button new theme copyWith doesn't change color

I've got a little piece of code below. It should show "add icon" with blue color. Instead it shows button with black color (as accentColor in MaterialApp).
Am I doing something wrong in "floatingActionButton"?
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
final appName = "Custom Themes";
return new MaterialApp(
title: appName,
theme: new ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.red[300],
accentColor: Colors.black,
),
home: new MyHomePage(
title: appName
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, #required this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: AppBar(
title: new Text(title),
),
body: new Center(
child: new Container(
color: Theme.of(context).primaryColor,
child: new Text(
"Text with background color",
style: Theme.of(context).textTheme.title,
),
),
),
floatingActionButton: new Theme(
data: Theme.of(context).copyWith(accentColor: Colors.blue),
child: new FloatingActionButton(
onPressed: null,
child: new Icon(Icons.add),
),
)
);
}
}
I watched a tutorial (it is flutter in iOS) and everything works like a charm there.
Tut is from April 2019. Maybe there is something that changed from that time?
You can use
Theme.of(context).copyWith(
colorScheme:
Theme.of(context).colorScheme.copyWith(secondary: Colors.blue),
)
detail reference https://flutter.dev/docs/cookbook/design/themes#complete-example
full code
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp( MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// TODO: implement build
final appName = "Custom Themes";
return MaterialApp(
title: appName,
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.red[300],
accentColor: Colors.black,
),
home: MyHomePage(
title: appName
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, #required this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Container(
color: Theme.of(context).primaryColor,
child: Text(
"Text with background color",
style: Theme.of(context).textTheme.title,
),
),
),
floatingActionButton: Theme(
data: Theme.of(context).copyWith(
colorScheme:
Theme.of(context).colorScheme.copyWith(secondary: Colors.blue),
),
child: FloatingActionButton(
onPressed: null,
child: Icon(Icons.add),
),
)
);
}
}