landfire13224
landfire13224

Reputation: 437

Why Flutter predefined theme won't apply automaticaly

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

Upvotes: 0

Views: 122

Answers (1)

Wessel
Wessel

Reputation: 786

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.

Upvotes: 1

Related Questions