CupertinoThemeData doesn't use specified primary color? - flutter

I have a class where I specify ThemeData for my app.
I use this class to set the appropriate theme in either the MaterialApp or CupertinoApp.
return CupertinoApp(
//...
theme: AppicationTheme.iosTheme()
//...
);
My IOS theme is provided as follows
static CupertinoThemeData iosTheme(){
return CupertinoThemeData(primaryColor: myPrimaryColor);
}
However when trying to set the color on an Icon, the primary color is still default blue as if never set to my color.

You are probably using Theme.of(context).primaryColor,
switch Theme to CupertinoTheme.
example:
Icon(Icons.access_alarm,<br>
color: CupertinoTheme.of(context).primaryColor,
),

Related

"theme: ThemeData..." apparently ignored starting with Flutter 2.5.0

I'm working through the startup_namer tutorial example from flutter.dev. Here's the definition of MyApp:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Startup Name Generator',
theme: ThemeData(
// Add the 3 lines from here...
primaryColor: Colors.white,
), // ... to here.
home: RandomWords());
}
}
It used to be that when I ran the app, the title bar would be white. But now, it retains the default (blue) theme. Looks like either ThemeData or at least primaryColor are being ignored. Does anyone know how to fix this? Thank you.
Checkout this link and this quote from the Flutter-Team:
The ThemeData accentColor, accentColorBrightness, accentIconTheme and
accentTextTheme properties have been deprecated.
The Material Design spec no longer specifies or uses an “accent” color
for the Material components. The default values for component colors
are derived from the overall theme’s color scheme. The ColorScheme’s
secondary color is now typically used instead of accentColor and the
onSecondary color is used when a contrasting color is needed.
Also checkout the migration guide.
Regarding your appBar problem do this within the ThemeData():
appBarTheme: AppBarTheme(backgroundColor: Colors.white),
This appears to be a regression: https://github.com/flutter/flutter/issues/89839.
Nowhere on the Flutter site does it say that primaryColor has been deprecated.

primary color isn't changing the Appbar color

I was following a YouTuber step by step creating this project but when I want to change the 'ThemeData primary colors' It just won't change and still remain the default color which is light blue. Here is a screenshot of it
According to AppBar description, it uses ColorScheme.primary by default.
The default app bar [backgroundColor] is the overall theme's
[ColorScheme.primary] if the overall theme's brightness is [Brightness.light]. Unfortunately this is the same as the default
[ButtonStyle.foregroundColor] for [TextButton] for light themes.
In this case a preferable text button foreground color is
[ColorScheme.onPrimary], a color that contrasts nicely with
[ColorScheme.primary]. to remedy the problem, override
[TextButton.style]:
try using colorScheme
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.purple,
),
),
home: MyApp(),
),
And to use somewhere else
Theme.of(context).colorScheme.primary,
For more, visit ThemeData-class

Changing the font family in Flutter when using ThemeData.dark() or ThemeData.light()

I'm trying to set the font of my MaterialApp. Since I'm using the dark theme, I'd like to just use copyWith and then change the fontFamily. However, copyWith doesn't have an option to change the fontFamily.
MaterialApp(
theme: ThemeData.dark().copyWith(
fontFamily: 'MyFontFamily',
),
The named parameter 'fontFamily' isn't defined.
How do I keep the dark theme but also change the font family? (Same problem with ThemeData.light().)
I found a solution and am posting below.
If you look at the source code for ThemeData.light() and ThemeData.dark(), you can see that all it does is set the brightness value:
/// A default light blue theme.
///
/// This theme does not contain text geometry. Instead, it is expected that
/// this theme is localized using text geometry using [ThemeData.localize].
factory ThemeData.light() => ThemeData(brightness: Brightness.light);
/// A default dark theme with a teal secondary [ColorScheme] color.
///
/// This theme does not contain text geometry. Instead, it is expected that
/// this theme is localized using text geometry using [ThemeData.localize].
factory ThemeData.dark() => ThemeData(brightness: Brightness.dark);
That means to solve your problem you don't need to bother with ThemeData.light() or ThemeData.dark(). Just create a new ThemeData and set the brightness yourself in addition to the fontFamily:
MaterialApp(
theme: ThemeData(
brightness: Brightness.dark,
fontFamily: 'MyFontFamily',
),
Since, all you're doing is setting the brightness, I think the easier way would be to just use DefaultTextStyle.
DefaultTextStyle(
style: TextStyle(
fontFamily: 'YourFontFamily',
),
child: YourWidget(),
)

In Flutter, how do you set *all* the scaffold background color at once?

Currently, I set background color of each screen using this:
#override
Widget build(BuildContext context) => Scaffold(
backgroundColor: Colors.white,
body: ...
);
Every time I create new screen, I always forgot to add this background color setter. This is a minor inconvenience, but I really appreciate if there's a method to set this background color once for all screens, unless overridden by backgroundColor property of specific Scaffold. I have tried to set the color on MaterialApp's color property, but it doesn't look like it has any effect.
You should pass custom ThemeData with background color parameter overwritten to you MaterialApp, so this will do the trick:
return MaterialApp(
// your other app initialization code
theme: ThemeData(scaffoldBackgroundColor: Colors.white),
);
You can read more about ThemData and flutter app theming in the official documentation
https://flutter.dev/docs/cookbook/design/themes

Add custom property to ThemeData in Flutter

I need to change color of a widget based on theme. I have separate ThemeData for light and dark theme. Now is it possible to add a custom property to ThemeData so that I can change the color of the widget based on theme and using that custom property?
Sadly, it appears that you simply can't - and the Flutter team doesn't seem to be interested in adding this, given their suggestion.
I think this is a major flaw, because we can't benefit from Theme.of(context) to automatically update all of our Widget that consume this ThemeData.
While some may say that you can use extensions to add new properties, you effectively won't know how to differ between multiple ThemeData (unless you can use some properties like Brightness, but I think this is just too hacky and not reliable to do so).
The alternative is to create another InheritedWidget (just like they said in the issue mentioned above) to handle your custom theme properties.
Edit: It seems that a new PR has introduced the possibility to extend the ThemeData, but it hasn't landed in main or even stable yet.
Flutter has recenty introduced ThemeExtensions (thanks #guilherme-matuella for the PR link!)
You can get a pretty good idea on how to use the functionality by following examples from the main Flutter repo:
return MaterialApp(
title: MyApp._title,
theme: ThemeData.light().copyWith(
extensions: <ThemeExtension<dynamic>>[
const MyColors(
brandColor: Color(0xFF1E88E5),
danger: Color(0xFFE53935),
),
],
),
darkTheme: ThemeData.dark().copyWith(
extensions: <ThemeExtension<dynamic>>[
const MyColors(
brandColor: Color(0xFF90CAF9),
danger: Color(0xFFEF9A9A),
),
],
),
themeMode: isLightTheme ? ThemeMode.light : ThemeMode.dark,
home: Home(
isLightTheme: isLightTheme,
toggleTheme: toggleTheme,
),
);
Which you can later retrieve in your widget like so:
final MyColors myColors = Theme.of(context).extension<MyColors>();
Instead of adding custom property, we can extend ThemeData by extension function. For example, if we need a custom property for color, we can add extension function on ColorScheme. Color dependencies are now moved to Themedata.
// checking brightness to support dynamic themeing
extension CustomColorSchemeX on ColorScheme {
Color get smallBoxColor1 =>
brightness == Brightness.light ? Colors.blue : Colors.grey[400];
}
And then access that property through Theme.of(context)...
Container(
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context)
.colorScheme
.smallBoxColor1),
),