0

I have a simple material app that has predefined theme like this:

final themeDark = ThemeData.dark()
.copyWith(
    iconTheme: IconThemeData(
        color: Colors.green,
    ),
);

But when I create a icon widget the color is still black, I need to manually write it like this to make it green:

class SwitchThemeButton extends StatelessWidget {
  SwitchThemeButton({Key? key, required this.onPressed}) : super(key: key);

  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      child: Icon(
        Icons.favorite,
        color: IconTheme.of(context).color,
      ),
      onPressed: onPressed,
    );
  }
}

I think the docs say that it will automatically use the current context IconThemeData.color if none are given? Then why this is happening??

The full code looks like this:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

final ThemeData themeDark = ThemeData.dark().copyWith(
  iconTheme: IconThemeData(
    color: Colors.green,
  ),
);

final ThemeData themeLight = ThemeData.light();

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  final _isDarkTheme = ValueNotifier<bool>(true);

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<bool>(
      valueListenable: _isDarkTheme,
      builder: (context, bool isDark, _) => MaterialApp(
        theme: isDark ? themeDark : themeLight,
        home: Scaffold(
          body: Stack(
            children: [
              Align(
                alignment: Alignment.center,
                child: MyWidget(),
              ),
              Align(
                alignment: Alignment.bottomRight,
                child: SwitchThemeButton(onPressed: _switchTheme),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _switchTheme() {
    _isDarkTheme.value = !_isDarkTheme.value;
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Make me green!', style: Theme.of(context).textTheme.headline4);
  }
}

class SwitchThemeButton extends StatelessWidget {
  SwitchThemeButton({Key? key, required this.onPressed}) : super(key: key);

  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      child: Icon(
        Icons.favorite,
      ),
      onPressed: onPressed,
    );
  }
}
landfire13224
  • 337
  • 4
  • 12

1 Answers1

1

Edit:

The problem turned out to be that Icon was wrapped in a FloatingActionButton, which has it's own theme that overrides its children. For the OP's code to work, a separate FAB theme should be specified. For most Icon use cases, the IconTheme does the trick

Original answer:

In relation to the first comment on the question, you need to specify themeDark as being the theme to use when the device is in dark mode, i.e.:

child: MaterialApp(
  title: 'MyApp',
  theme: themeLight,
  darkTheme: themeDark,
  home: MyHomePage(),
),

Since you say the Icons are still black, I suspect you don't specify the darkTheme: in dark mode, icons are white by default. In light mode, they are black.

Wessel
  • 617
  • 4
  • 13
  • Do I need to provide the dark one in darkTheme parameter? I wrote the code as I mentioned above is it incorrect? – landfire13224 Apr 08 '21 at 17:53
  • Yes, the MaterialApp widget allows for two themes: the default theme and the darkTheme.You can specify the theme the way you did it (final themeDark = ThemeData.dark().copywith(...), but you then have to pass the themeDark to the darkTheme parameter of MaterialApp. See also https://stackoverflow.com/a/62607827/14567247 – Wessel Apr 09 '21 at 18:21
  • Thanks for the info, I just tried that by assign both my light and dark in their own parameter and specify the mode depending on the current theme. But yet the icon color still uses the default one (black).. Any idea why? – landfire13224 Apr 09 '21 at 18:50
  • Is your device in dark mode? The ThemeData specified by the theme parameter is the default, the other is only chosen when your phone is in dark mode. If your device does not support dark mode, try swapping the theme and darkTheme and see if the icons changed – Wessel Apr 09 '21 at 18:51
  • I initially have a dark theme as the default one, swapping it back and forth also won't change anything it will only turn it black and then white, apparently, it's not that it doesn't work in fact I could access the IconThemeData.color as green meaning that it works as intended, probably there's more into the framework itself but yet I don't find anything useful in the docs regarding the problem. – landfire13224 Apr 09 '21 at 20:58
  • Interesting; so the themes do change but the green color isn't properly passed through. Can you show me what the icon code looks like? – Wessel Apr 10 '21 at 22:02
  • I have added the full code, just copy paste it in dartpad. I think it will be clearer if you see it by yourself. – landfire13224 Apr 11 '21 at 23:20
  • Ah I see. Your icon is wrapped in a FloatingActionButton, which has its own FloatingActionButtonTheme.The FAB theme overrides the Icon theme. If you remove the FAB and show only the icon, it is indeed green. You can specify the FAB theme in your themeDark along with the icon theme. – Wessel Apr 13 '21 at 06:59
  • 1
    Holy.. that's crazy I just tested that and it was true. I don't know that FAB reprocess my icon color! You probably want to rewrite your answer so that people in the future don't confuse by this, I will select it as well. Thanks. – landfire13224 Apr 13 '21 at 20:03