Coder Social home page Coder Social logo

birjuvachhani / adaptive_theme Goto Github PK

View Code? Open in Web Editor NEW
464.0 7.0 37.0 703 KB

Easiest way to add support for light and dark theme in your flutter app.

Home Page: https://pub.dev/packages/adaptive_theme

License: Apache License 2.0

Dart 94.66% Kotlin 0.12% Swift 1.01% Objective-C 0.04% Ruby 2.67% HTML 1.50%
flutter theme adaptive flutter-ui flutter-package flutter-widget hactoberfest hactoberfest-accepted hacktoberfest hacktoberfest2023

adaptive_theme's Introduction

adaptive_theme

Adaptive Theme

Easiest way to add support for light and dark theme in your Flutter app. It allows to manually set light or dark theme and also lets you define themes based on the system. It also persists the theme modes changes across app restarts.

Build Tests Codecov Pub Version

Demo: Adaptive Theme

Index

Getting Started

add following dependency to your pubspec.yaml

dependencies:
  adaptive_theme: <latest_version>

Initialization

You need to wrap your MaterialApp with AdaptiveTheme in order to apply themes.

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
      light: ThemeData.light(useMaterial3: true),
      dark: ThemeData.dark(useMaterial3: true),
      initial: AdaptiveThemeMode.light,
      builder: (theme, darkTheme) => MaterialApp(
        title: 'Adaptive Theme Demo',
        theme: theme,
        darkTheme: darkTheme,
        home: MyHomePage(),
      ),
    );
  }
}

Changing Theme Mode

Now that you have initialized your app as mentioned above. It's very easy and straight forward to change your theme modes: light to dark, dark to light or to system default.

// sets theme mode to dark
AdaptiveTheme.of(context).setDark();

// sets theme mode to light
AdaptiveTheme.of(context).setLight();

// sets theme mode to system default
AdaptiveTheme.of(context).setSystem();

Toggle Theme Mode

AdaptiveTheme allows you to toggle between light, dark and system theme the easiest way possible.

AdaptiveTheme.of(context).toggleThemeMode();

Changing Themes

If you want to change the theme entirely like change all the colors to some other color swatch, then you can use setTheme method.

AdaptiveTheme.of(context).setTheme(
  light: ThemeData(
    useMaterial3: true,
    brightness: Brightness.light,
    colorSchemeSeed: Colors.purple,
  ),
  dark: ThemeData(
    useMaterial3: true,
    brightness: Brightness.dark,
    colorSchemeSeed: Colors.purple,
  ),
);

Reset Theme

AdaptiveTheme is smart enough to keep your default themes handy that you provided at the time of initialization. You can fallback to those default themes in a very easy way.

AdaptiveTheme.of(context).reset();

This will reset your theme as well as theme mode to the initial values provided at the time of initialization.

Set Default Theme

AdaptiveTheme persists theme mode changes across app restarts and uses the default themes to set theme modes(light/dark) on. You can change this behavior if you want to set a different theme as default theme other then the one provided at the time of initialization.

This comes handy when you're fetching themes remotely on app starts and setting theme as current theme.

Doing so is quit easy. You would set a new theme normally as you do by calling setTheme method but this time, with a flag isDefault set to true.

This is only useful when you might want to reset to default theme at some point.

AdaptiveTheme.of(context).setTheme(
  light: ThemeData(
    useMaterial3: true,
    brightness: Brightness.light,
    colorSchemeSeed: Colors.blue,
  ),
  dark: ThemeData(
    useMaterial3: true,
    brightness: Brightness.dark,
    colorSchemeSeed: Colors.blue,
  ),
  isDefault: true,
);

Get ThemeMode at App Start

When you change your theme, next app run won't be able to pick the most recent theme directly before rendering with default theme first time. This is because at time of initialization, we cannot run async code to get previous theme mode. However it can be avoided if you make your main() method async and load previous theme mode asynchronously. Below example shows how it can be done.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final savedThemeMode = await AdaptiveTheme.getThemeMode();
  runApp(MyApp(savedThemeMode: savedThemeMode));
}
AdaptiveTheme(
  light: lightTheme,
  dark: darkTheme,
  initial: savedThemeMode ?? AdaptiveThemeMode.light,
  builder: (theme, darkTheme) => MaterialApp(
    title: 'Adaptive Theme Demo',
    theme: theme,
    darkTheme: darkTheme,
    home: MyHomePage(),
  ),
)

Notice that I passed the retrieved theme mode to my material app so that I can use it while initializing the default theme. This helps avoiding theme change flickering on app startup.

Listen to the theme mode changes

You can listen to the changes in the theme mode via a ValueNotifier. This can be useful when designing theme settings screen or developing ui to show theme status.

AdaptiveTheme.of(context).modeChangeNotifier.addListener(() {
  // do your thing.
});

Or you can utilize it to react on UI with

ValueListenableBuilder(
  valueListenable: AdaptiveTheme.of(context).modeChangeNotifier,
  builder: (_, mode, child) {
    // update your UI
    return Container();
  },
);

Using floating theme button overlay

Starting from v3.3.0, you can now set debugShowFloatingThemeButton to true and enable a floating button that can be used to toggle theme mode very easily. This is useful when you want to test your app with both light and dark theme without restarting the app or navigating to settings screen where your theme settings are available.

AdaptiveTheme(
  light: ThemeData.light(),
  dark: ThemeData.dark(),
  debugShowFloatingThemeButton: true, // <------ add this line
  initial: AdaptiveThemeMode.light,
  builder: (theme, darkTheme) => MaterialApp(
    theme: theme,
    darkTheme: darkTheme,
    home: MyHomePage(),
  ),
);
floating_button.mp4

Ceveats

Non-Persist theme changes

This is only useful in scenarios where you load your themes dynamically from network in the splash screen or some initial screens of the app. Please note that AdaptiveTheme does not persist the themes, it only persists the theme modes(light/dark/system). Any changes made to the provided themes won't be persisted and you will have to do the same changes at the time of the initialization if you want them to apply every time app is opened. e.g changing the accent color.

Using SharedPreferences

This package uses shared_preferences plugin internally to persist theme mode changes. If your app uses shared_preferences which might be the case all the time, clearing your shared_preferences at the time of logging out or signing out might clear these preferences too. Be careful not to clear these preferences if you want it to be persisted.

/// Do not remove this key from preferences
AdaptiveTheme.prefKey

You can use above key to exclude it while clearing the all the preferences.

Or you can call AdaptiveTheme.persist() method after clearing the preferences to make it persistable again as shown below.

final prefs = await SharedPreferences.getInstance();
await prefs.clear();
AdaptiveTheme.persist();

Using CupertinoTheme

Wrap your CupertinoApp with CupertinoAdaptiveTheme in order to apply themes.

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return CupertinoAdaptiveTheme(
      light: CupertinoThemeData(
        brightness: Brightness.light,
      ),
      dark: CupertinoThemeData(
        brightness: Brightness.dark,
      ),
      initial: AdaptiveThemeMode.light,
      builder: (theme) => CupertinoApp(
        title: 'Adaptive Theme Demo',
        theme: theme,
        darkTheme: darkTheme,
        home: MyHomePage(),
      ),
    );
  }
}

Changing Cupertino Theme

// sets dark theme
CupertinoAdaptiveTheme.of(context).setDark();

// sets light theme
CupertinoAdaptiveTheme.of(context).setLight();

// sets system default theme
CupertinoAdaptiveTheme.of(context).setSystem();

Contribution

You are most welcome to contribute to this project!

Please have a look at Contributing Guidelines, before contributing and proposing a change.

Liked Adaptive Theme?

Show some love and support by starring the repository.

Or You can

Buy Me A Coffee

License

Copyright ยฉ 2020 Birju Vachhani

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

adaptive_theme's People

Contributors

bernhardfrenking avatar birjuvachhani avatar pavel-sulimau avatar phil9l avatar sadrakafiri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

adaptive_theme's Issues

Make it possible to track only billable hours

Is your feature request related to a problem? Please describe.
I use toggl to track both work-related things and personal development "tasks" that I set for myself. However the billable hours are the "important" ones for me, so it would be great if I could exclude non-billable hours when figuring out if I've achieved my target or not.

Describe the solution you'd like
It would be great to have a setting that says something like "Exclude non-billable hours"

Not working when copying demo StatelessWidget code

Hi, I changed the code slightly so that it ignores bold text in iOS accessibility and now it doesn't work even if i take away the modifications. here is my code:

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
        light: ThemeData(
          brightness: Brightness.light,
          primaryColor: Colors.red,
        ),
        dark: ThemeData(
          brightness: Brightness.dark,
          primaryColor: Colors.red,
        ),
        initial: AdaptiveThemeMode.dark,
        builder: (theme, darkTheme) => MediaQuery(
            data: MediaQueryData.fromWindow(WidgetsBinding.instance.window)
                .copyWith(boldText: false),
            child: MaterialApp(
              useInheritedMediaQuery: true,
              title: 'Reggie',
              theme: theme,
              darkTheme: darkTheme,
              home: const MyHomePage(title: 'Reggie'),
            )));
  }
}

Screenshot 2022-07-29 at 21 18 47

Here are simulator screenshots. Running in debug mode using VSCode to start

The accent colour which should be on the top appbar does not appear as red and neither does the floatingActionButton.

Notify listener when changing theme mode

Describe the bug
Widgets that depend on AdaptiveTheme.of(context) don't rebuild automatically after changing the theme. I guess it is because we are not using an InheritedWidget. The problem is especially annoying for a larger app, where one has to call setState manually everywhere.

Example

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final savedThemeMode = await AdaptiveTheme.getThemeMode();
  runApp(MyApp(savedThemeMode: savedThemeMode));
}

class MyApp extends StatelessWidget {
  final AdaptiveThemeMode? savedThemeMode;

  const MyApp({Key? key, this.savedThemeMode}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
      light: ThemeData(
        brightness: Brightness.light,
        primarySwatch: Colors.red,
        accentColor: Colors.amber,
      ),
      dark: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.red,
        accentColor: Colors.amber,
      ),
      initial: savedThemeMode ?? AdaptiveThemeMode.light,
      builder: (theme, darkTheme) => MaterialApp(
        title: 'Adaptive Theme Demo',
        theme: theme,
        darkTheme: darkTheme,
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    final theme = AdaptiveTheme.of(context);
    return Scaffold(
      appBar: AppBar(title: Text('Adaptive Theme Demo')),
      body: Center(
        child: TextButton(
          onPressed: () {
            showDialog(context: context, builder: (_) => const ThemeDialog());
          },
          child: Icon(
            theme.mode == AdaptiveThemeMode.light
                ? Icons.wb_sunny_outlined
                : theme.mode == AdaptiveThemeMode.dark
                    ? Icons.bedtime_outlined
                    : Icons.brightness_auto_outlined,
          ),
        ),
      ),
    );
  }
}

class ThemeDialog extends StatefulWidget {
  const ThemeDialog({Key? key}) : super(key: key);

  @override
  _ThemeDialogState createState() => _ThemeDialogState();
}

class _ThemeDialogState extends State<ThemeDialog> {
  @override
  Widget build(BuildContext context) {
    final adaptiveTheme = AdaptiveTheme.of(context);
    return AlertDialog(
      title: const Text('Theme'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          RadioListTile<AdaptiveThemeMode>(
            autofocus: true,
            selected: true,
            dense: true,
            title: const Text('Light', style: TextStyle(fontSize: 14)),
            value: AdaptiveThemeMode.light,
            onChanged: (value) => adaptiveTheme.setThemeMode(value!),
            groupValue: adaptiveTheme.mode,
          ),
          RadioListTile<AdaptiveThemeMode>(
            autofocus: true,
            selected: true,
            dense: true,
            title: const Text('Dark', style: TextStyle(fontSize: 14)),
            value: AdaptiveThemeMode.dark,
            onChanged: (value) => adaptiveTheme.setThemeMode(value!),
            groupValue: adaptiveTheme.mode,
          ),
          RadioListTile<AdaptiveThemeMode>(
            autofocus: true,
            selected: true,
            dense: true,
            title: const Text('System', style: TextStyle(fontSize: 14)),
            value: AdaptiveThemeMode.system,
            onChanged: (value) => adaptiveTheme.setThemeMode(value!),
            groupValue: adaptiveTheme.mode,
          ),
        ],
      ),
      actions: <Widget>[
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text(
            MaterialLocalizations.of(context).okButtonLabel,
            style: Theme.of(context).primaryTextTheme.button,
          ),
        ),
      ],
    );
  }
}

Expected behavior
I expected that when I change the theme, widget that depend on AdaptiveTheme.of(context) will rebuild itself automatically. But unfortunately this is not the case and I have to call setState manually. This is especially noticeable when I switch between e.g. Light and System mode (and the System mode is Light).

[Question] How to get 'Get ThemeMode At App Start', working?

Following Get ThemeMode at App Start, my code looks like this:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final savedThemeMode = await AdaptiveTheme.getThemeMode();
  runApp(MyApp(savedThemeMode: savedThemeMode)); // error here!
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
      light:
          ThemeData(brightness: Brightness.light, primarySwatch: Colors.pink),
      dark:
          ThemeData(brightness: Brightness.dark, primarySwatch: Colors.teal),
      initial: savedThemeMode ?? AdaptiveThemeMode.light,
      builder: (theme, darktheme) => MaterialApp(
        title: 'Schedule',
        theme: theme,
        darkTheme: darktheme,
        home: MyHomePage(
          title: 'Schdeule',
        ),
      )
    );
  }
}

But I get an error saying:

The named parameter 'savedThemeMode' isn't defined.
Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'savedThemeMode'.dart(undefined_named_parameter)

Please pardon my ignorance in Dart and/or Flutter and show me how to resolve this.

Get current theme?

Is there any way to determine current theme and showing different icon for iconbutton?
lightbulb for light theme and lightbulb_outline for dark theme?

IconButton(
    icon: Icon(Icons.lightbulb_outline),
    onPressed: () {
        AdaptiveTheme.of(context).toggleThemeMode();
    },
)

Rebuild in `IndexedStack`

Describe the bug
When we use IndexedStack and go to other tabs, the operation of changing color or color mode is not done properly!
It is necessary to rebuild the tab to fix it!

Expected behavior
I expected the color change to work well in other tabs.

Screenshots
In these screenshots, I went from light to dark mode, but some parts have not changed yet!

Bug screenshot
Screenshot from 2023-10-29 11-18-27

Correct screenshot
Screenshot from 2023-10-29 11-15-45

Desktop (please complete the following information):

  • OS: Linux
  • Browser: Chrome
  • Version: 118.0.5993.117

Smartphone (please complete the following information):

  • Device: Android
  • OS: Api 29
  • Browser: Chrome
  • Version: 118.0.5993.111

Additional context
Currently I have to use a global listener in all tabs to rebuild the tab!

Flutter 3.0 build error

Describe the bug
Can't build the project with Flutter 3.0

To Reproduce
Steps to reproduce the behavior:

  1. Upgrade to Flutter 3.0
  2. Build the application

Expected behavior
Working app

Screenshots
image

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: Android 7.1.2

Additional context
i am using version 2.3.1

How to change default light white mode

I don't want to use light mode how do I use my own custom theme color (orange) with dark mode ?

For example this my code

    `AdaptiveTheme(
      light: ThemeData(
        brightness: Brightness.light,
        primarySwatch: Colors.blue,
      ),
      dark: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.orange,
      ),
      initial: AdaptiveThemeMode.light,
      builder: (theme, darkTheme) => GetMaterialApp(
        debugShowCheckedModeBanner: false,
        theme: theme,
        darkTheme: darkTheme,
        home:  MyHome(),
        ),
        ),
        
       SwitchListTile(
        activeColor: Colors.orange,
        value: darkmode,
        onChanged: (bool value) {
          print(value);
          if (value == true) {
            AdaptiveTheme.of(context).setDark();
          } else {
            AdaptiveTheme.of(context).setLight();
          }
          setState(() {
            darkmode = value;
          });
        },
        ),`

Shared Preferences versions conflict

I need to use the 2.0 version of Shared_Preferences for NullSafety reason and others fix. I have to use Adaptative_Theme because this is awesome and so clear ! But it seems I have a conflict with version requirements :

/Users/fred/Documents/Flutter/development/flutter/bin/flutter --no-color pub get
Running "flutter pub get" in weekpath...

Because adaptive_theme 1.1.0 depends on shared_preferences >=0.5.0 <1.0.0 and no versions of adaptive_theme match >1.1.0 <2.0.0, adaptive_theme ^1.1.0 requires shared_preferences >=0.5.0 <1.0.0.
So, because depends on both adaptive_theme ^1.1.0 and shared_preferences ^2.0.4, version solving failed.
pub get failed (1; So, because depends on both adaptive_theme ^1.1.0 and shared_preferences ^2.0.4, version solving failed.)

It is possible to update adaptative_theme or a way to change something as workaround ?

Thank you, Fred

Font not working correctly

Thank you for the library..

I noticed when I set the default font its not applied for the whole application

This is my code

AdaptiveTheme(
light: ThemeData(
primaryColor: MaterialWhite,
accentColor: orangeColorDark,
inputDecorationTheme: const InputDecorationTheme(
labelStyle: TextStyle(color: Colors.grey),
hintStyle: TextStyle(color: Colors.grey),
),
primaryTextTheme: TextTheme(
headline6: TextStyle(
color: Colors.black,
),
bodyText2: TextStyle(
color: Colors.black,
),
bodyText1: TextStyle(
color: Colors.black,
),
headline1: TextStyle(
color: Colors.black,
),
headline2: TextStyle(
color: Colors.black,
),
headline3: TextStyle(
color: Colors.black,
),
headline4: TextStyle(
color: Colors.black,
),
headline5: TextStyle(
color: Colors.black,
),
subtitle1: TextStyle(
color: Colors.black,
),
subtitle2: TextStyle(
color: Colors.black,
),
),
fontFamily: checkLanguage() ? 'lato_regular' : 'sans_full',
textTheme: Theme.of(context).textTheme.apply(
bodyColor: Colors.black,
displayColor: Colors.black,
),
scaffoldBackgroundColor: HexColor('#ffffff'),
backgroundColor: HexColor('#ffffff'),
),
dark: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.red,
accentColor: Colors.amber,
appBarTheme: AppBarTheme(
backgroundColor: HexColor('#121212'),
centerTitle: true,
elevation: 0),
scaffoldBackgroundColor: HexColor('#212121'),
backgroundColor: HexColor('#212121'),
primaryTextTheme: TextTheme(
headline6: TextStyle(
color: Colors.white,
),
bodyText2: TextStyle(
color: Colors.white,
),
bodyText1: TextStyle(
color: Colors.white,
),
headline1: TextStyle(
color: Colors.white,
),
headline2: TextStyle(
color: Colors.white,
),
headline3: TextStyle(
color: Colors.white,
),
headline4: TextStyle(
color: Colors.white,
),
headline5: TextStyle(
color: Colors.white,
),
subtitle1: TextStyle(
color: Colors.white,
),
subtitle2: TextStyle(
color: Colors.white,
),
),
textTheme: Theme.of(context).textTheme.apply(
bodyColor: Colors.white,
displayColor: Colors.white,
),
fontFamily: checkLanguage() ? 'lato_regular' : 'sans_full',
),

Smartphone (please complete the following information):

  • Device: Simulator iPhone11
  • OS: iOS13.5

Set system theme not functioning

Describe the bug
I have three simple buttons to toggle between the various theme modes. But it seems only setLight and setDark methods work. setSystem method instead of setting to the device theme sets the theme to light even when the device is in dark mode.

To Reproduce
Code to reproduce the behavior:

Container(
child: Column(
children: [
// light theme
FlatButton(
onPressed: () {
AdaptiveTheme.of(context).setLight();
},
child: Text('Set light')),

          // dark theme
          FlatButton(
              onPressed: () {
                AdaptiveTheme.of(context).setDark();
              },
              child: Text('Set  dark')),

          // system theme
          FlatButton(
              onPressed: () {
                AdaptiveTheme.of(context).setSystem();
              },
              child: Text('Set  system')),
        ],
      ),

)

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser chrome
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: Samsung A10s (actual device) and a Google Pixel emulator
  • OS: Android 10
  • Browser: no browser
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Theme doesn't change on safari.

Describe the bug
I am unable to change theme from light to dark and vice versa. On Safari.

To Reproduce
Steps to reproduce the behavior:

  1. Go to website and select slider to change theme. It doesn't work on Safari

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: iMac 2022 Monterey
  • Browser: Safari
  • Version: adaptive_theme: ^2.3.1

Additional context
I think the themes doesn't w\switch from light to dark and vice versa because of how you saved settings in cookies.

In flutter 3.10 AdaptiveThemeMode.system won't work as it should be.

Describe the bug
When the theme mode is AdaptiveThemeMode.system and the current phone's system theme is dark mode and when you launch the app it will display the dark theme. but while the app is opened and when you change the the phone's system theme to light mode the app will not reflect to the change. but after restart it will change to light mode.

but vice versa is still working fines, when you launch the app from light mode.

before flutter 3.10 it works as it should.

To Reproduce
Steps to reproduce the behavior:

  1. make sure AdaptiveThemeMode.system is applied.
  2. if the app is opened close it.
  3. change the system theme to dark mode
  4. launch the app
  5. we will see the dark mode applied to the app
  6. change the systems theme to light mode while the app is opened.
  7. the UI won't change to light.
  8. but if I restart the app, the light mode will be applied.

Expected behavior
when changing the systems theme from dark to light, the app should also react to that.

Screenshots
No need.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: Samsung galaxy a12 - real device

Additional context
Add any other context about the problem here.

The app is starting on dark theme even after setting the initial theme as light mode.

The app is starting on dark theme even after setting the initial theme as light mode. If I remove the Adaptive theme code and set the app theme to light mode in Material app it works fine.

Here I have set the app theme explicitly to light mode.

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
      light: AppTheme.lightTheme,
      dark: AppTheme.darkTheme,
      initial: AdaptiveThemeMode.light, // <- Explicit light mode
      builder: (theme, darkTheme) {
        return MaterialApp(
          title: 'HexaWriter',
          theme: theme,
          darkTheme: darkTheme,
          debugShowCheckedModeBanner: false,
          home: const SplashScreen(),
        );
      },
    );
  }
}

and here is my app theme code

class AppTheme {
  AppTheme._();

  static ThemeData lightTheme = ThemeData(
    useMaterial3: true,
    colorScheme: const ColorScheme.light(
      primary: primaryColor,
      secondary: secondaryColor,
      surface: surfaceColor,
      error: errorColor,
      onPrimary: onPrimaryColor,
      onSecondary: onSecondaryColor,
      onSurface: onSurfaceColor,
      onError: onErrorColor,
    ),
    scaffoldBackgroundColor: Colors.white,
    textTheme: GoogleFonts.outfitTextTheme().apply(bodyColor: Colors.black, displayColor: Colors.black),
    inputDecorationTheme: InputTheme.light,
    checkboxTheme: CheckboxThemeData(
      fillColor: WidgetStateProperty.all(primaryColor),
    ),
    radioTheme: RadioThemeData(
      fillColor: WidgetStateProperty.all(primaryColor),
    ),
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        backgroundColor: primaryColor,
        foregroundColor: onPrimaryColor,
        disabledForegroundColor: Colors.grey,
      ),
    ),
    textButtonTheme: TextButtonThemeData(
      style: TextButton.styleFrom(
        foregroundColor: primaryColor,
        disabledForegroundColor: Colors.grey,
      ),
    ),
    outlinedButtonTheme: OutlinedButtonThemeData(
      style: OutlinedButton.styleFrom(
        foregroundColor: primaryColor,
        disabledForegroundColor: Colors.grey,
      ),
    ),
    tabBarTheme: const TabBarTheme(
      unselectedLabelColor: unselectedItemColor,
    ),
    navigationRailTheme: const NavigationRailThemeData(
      unselectedIconTheme: IconThemeData(color: unselectedItemColor),
      unselectedLabelTextStyle: TextStyle(color: unselectedItemColor),
    ),
    bottomNavigationBarTheme: const BottomNavigationBarThemeData(
      unselectedItemColor: unselectedItemColor,
    ),
    navigationBarTheme: const NavigationBarThemeData(
      indicatorColor: primaryColor,
    ),
  );

  static ThemeData darkTheme = ThemeData(
    useMaterial3: true,
    colorScheme: const ColorScheme.dark(
      primary: darkPrimaryColor,
      secondary: darkSecondaryColor,
      surface: darkSurfaceColor,
      error: darkErrorColor,
      onPrimary: darkOnPrimaryColor,
      onSecondary: darkOnSecondaryColor,
      onSurface: darkOnSurfaceColor,
      onError: darkOnErrorColor,
    ),
    textTheme: GoogleFonts.outfitTextTheme().apply(bodyColor: Colors.white, displayColor: Colors.white),
    inputDecorationTheme: InputTheme.dark,
    checkboxTheme: CheckboxThemeData(
      fillColor: WidgetStateProperty.all(darkPrimaryColor),
    ),
    radioTheme: RadioThemeData(
      fillColor: WidgetStateProperty.all(darkPrimaryColor),
    ),
    elevatedButtonTheme: ElevatedButtonThemeData(
      style: ElevatedButton.styleFrom(
        backgroundColor: darkPrimaryColor,
        foregroundColor: darkOnPrimaryColor,
        disabledForegroundColor: Colors.grey,
      ),
    ),
    textButtonTheme: TextButtonThemeData(
      style: TextButton.styleFrom(
        foregroundColor: darkPrimaryColor,
        disabledForegroundColor: Colors.grey,
      ),
    ),
    outlinedButtonTheme: OutlinedButtonThemeData(
      style: OutlinedButton.styleFrom(
        foregroundColor: darkPrimaryColor,
        disabledForegroundColor: Colors.grey,
      ),
    ),
    tabBarTheme: const TabBarTheme(
      unselectedLabelColor: darkUnselectedItemColor,
    ),
    navigationRailTheme: const NavigationRailThemeData(
      unselectedIconTheme: IconThemeData(color: darkUnselectedItemColor),
      unselectedLabelTextStyle: TextStyle(color: darkUnselectedItemColor),
    ),
    bottomNavigationBarTheme: const BottomNavigationBarThemeData(
      unselectedItemColor: darkUnselectedItemColor,
    ),
  );
}

Dark Mode and Macbook with dark theme

Describe the bug
When you set dark theme on macbook and run the app on chrome (WEB), the library return always dark theme

To Reproduce
Run the app on a macbook with dark theme set.
Try ti switch to light theme. It doesn't work.

If macbook theme is on light or automatic non problem occur.

Library version 2.1.0
Flutter version 2.0.4
MacOS Big Sure 11.2.3

BR

toggle theme on icon button click bug

Describe the bug
Thank you for preparing such a package first of all. When I assign the toggletheme code to the icon button, it does not detect some clicks. It works when I click it again.

When I first open the application, the theme does not change at the first click. It changes when I click it for the second time. Nothing happens on the first click.

Smartphone

  • Device: iPhone 11 Simulator
  • OS: iOS 13.0
  • Version : flutter version 3.0.3, adaptive theme version 3.1.0

Bug Video :

Kapture.2022-07-07.at.14.02.48.mp4

Codes :

app.dart

 class MyApp extends StatelessWidget {
  MyApp({Key? key,required this.savedThemeMode}) : super(key: key);
  var savedThemeMode;
  @override
  Widget build(BuildContext context) {
    // App Theme
    final appTheme = AppTheme();
    return AdaptiveTheme(
      light: appTheme.lightTheme,
      dark: appTheme.darkTheme,
      initial: savedThemeMode ?? AdaptiveThemeMode.light,
      builder: (theme,darkTheme) => MaterialApp(
        title: 'Material App',
        theme: theme,
        darkTheme: darkTheme,
        home: const HomeView(),
      ),
    );
  }
} 

homeView.dart

class HomeView extends StatelessWidget {
  const HomeView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home View'),
        actions: [
          IconButton(
            icon: Icon(Icons.settings),
            onPressed: () {
              AdaptiveTheme.of(context).toggleThemeMode();
            },
          ),
        ],
      ),
      body: Center(
        child: Container(
          child: Text('Hello World'),
        ),
      ),
    );
  }
} 

App theme doesn't update if app is started while the system was in dark mode

Describe the bug
App theme doesn't update if the app is started while the system was in dark mode.
I have only tested this on an Android 11 phone, the Oneplus Nord.

The code

class MyApp extends StatelessWidget
{
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context)
  {
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);

    // Auto-reset immersive mode on UI change after 1 sec
    SystemChrome.setSystemUIChangeCallback
    (
      (systemOverlaysAreVisible) => Future.delayed
      (
        const Duration(seconds: 2),
        ()
        {
          SystemChrome.restoreSystemUIOverlays();
        }
      )
    );

    return AdaptiveTheme
    (
      light: AppTheme.lightTheme, // Custom Material theme overrides
      dark: AppTheme.darkTheme,
      initial: AdaptiveThemeMode.system,
      builder: (theme, darkTheme)
      {
        return MaterialApp
        (
          supportedLocales: const
          [
            Locale('en'),
            Locale('fr'), // Fallback lang
          ],

          localizationsDelegates:
          [
            FlutterI18nDelegate
              (
              translationLoader: FileTranslationLoader
                (
                  basePath: 'assets/i18n',
                  fallbackFile: 'fr'
              ),
              missingTranslationHandler: (key, locale)
              {
                if (kDebugMode)
                {
                  print("i18n --- Missing Key: $key, languageCode: ${locale?.languageCode}");
                }
              },
            ),
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate
          ],

          debugShowCheckedModeBanner: true,
          title: 'My App',
          initialRoute: '/',
          routes: AppRoutes.appRoutes,
          theme: theme,
          darkTheme: darkTheme,
        );
      }
    );
  }
}

Environment

  • OS: Android 11
  • adaptive_theme: 2.3.0

Additional info

  • I've noticed that, if I change the system from light/dark mode when the theme isn't updating, I don't even get a log message in my flutter run session. I do get logs notifying a theme change when I start the app when the system is in light mode, however.

  • So far I don't know if the issue is with my code or your package, I'll be very grateful if you could help me on this.

  • Note that the issue appears regardless if the app is in release or debug mode.

got this bug when i upgraded to flutter 3.0

currently im using flutter web 3.0 . when i upgraded to this flutter version , i got this error on my consol ๐Ÿ‘

/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/adaptive_theme-2.3.1/lib/src/adaptive_theme.dart:218:20: Warning: Operand of null-aware operation '?.' has type 'WidgetsBinding' which excludes null.

  • 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/binding.dart').
    package:flutter/โ€ฆ/widgets/binding.dart:1
    WidgetsBinding.instance?.removeObserver(this);

Before, when i was using an older version, this error did not appear. can you please guide ? thanks

System mode does not work on macOS

Describe the bug
When I launch my app on macOS and set the mode to system, the theme is not matched to the macOS system theme. The system theme works fine on Android and iOS.

CupertinoApp - Dynamic Theme Change Issue

Describe the bug
Issue occurs when you try to change theme in a CupertinoApp with No Material app

To Reproduce
Steps to reproduce the behavior:
Use CupertinoApp and try to change theme dynamically

Expected behavior
Change Theme , but no

Additional context

E/flutter (24247): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value
E/flutter (24247): #0      AdaptiveTheme.of (package:adaptive_theme/src/adaptive_theme.dart:72:45)
E/flutter (24247): #1      _AppScreenState.afterFirstLayout (package:app/app_screen.dart:86:19)
E/flutter (24247): #2      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:846:45)
E/flutter (24247): #3      Future._propagateToListeners (dart:async/future_impl.dart:875:13)
E/flutter (24247): #4      Future._completeWithValue (dart:async/future_impl.dart:647:5)
E/flutter (24247): #5      Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:721:7)
E/flutter (24247): #6      _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (24247): #7      _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
E/flutter (24247): 

Basically,

        AdaptiveTheme.of(context).setLight();

doesn't work with CupertinoApp

System status bar not changing color on iOS

When light theme mode or dark theme mode is chosen, the system status bar on an iOS device keeps the system color. For example, when light theme mode is active and i change the system theme, the color of the status bar text changes with it, instead of keeping the black text color. The same thing happens on dark theme mode. On system theme mode it works perfectly. Im using adaptive_theme: ^2.1.1. Flutter version 2.0.3.

unable to change to light mode

happening on iOS haven't tested on other platforms; trying to change the initial value to light or system doesn't work even when MediaQuery reads the theme correctly.

not sure what im doing wrong here

Widget build(BuildContext context) {
    return AdaptiveTheme(
      light: ThemeData.light().copyWith(
          brightness: Brightness.light,
          primaryColor: (Platform.isIOS || Platform.isMacOS)
              ? CupertinoTheme.of(context).primaryColor
              : Theme.of(context).primaryColor,
          dividerColor: CupertinoColors.inactiveGray,
          scaffoldBackgroundColor: CupertinoColors.white,
          cardColor: CupertinoColors.systemGroupedBackground,
          primaryIconTheme:
              Theme.of(context).primaryIconTheme.copyWith(color: Colors.black),
          textTheme: Theme.of(context).textTheme.copyWith(
              bodyText1: Theme.of(context)
                  .textTheme
                  .bodyText1!
                  .copyWith(color: CupertinoColors.black),
              subtitle1: Theme.of(context)
                  .textTheme
                  .subtitle1!
                  .copyWith(color: CupertinoColors.black),
              subtitle2: Theme.of(context).textTheme.subtitle2!.copyWith(
                  color: CupertinoTheme.of(context)
                      .textTheme
                      .tabLabelTextStyle
                      .color),
              headline6: Theme.of(context).textTheme.headline6!.copyWith(
                    fontWeight: CupertinoTheme.of(context)
                        .textTheme
                        .navLargeTitleTextStyle
                        .fontWeight,
                    color: (Platform.isIOS || Platform.isMacOS)
                        ? CupertinoTheme.of(context).textTheme.textStyle.color
                        : Theme.of(context).textTheme.subtitle1!.color,
                  ),
              headline4: Theme.of(context).textTheme.headline4!.copyWith(
                  fontWeight: CupertinoTheme.of(context)
                      .textTheme
                      .navLargeTitleTextStyle
                      .fontWeight,
                  color: (Platform.isIOS || Platform.isMacOS)
                      ? CupertinoColors.white
                      : Theme.of(context).textTheme.subtitle1!.color)),
          appBarTheme: Theme.of(context).appBarTheme.copyWith(
              backgroundColor: CupertinoTheme.of(context).barBackgroundColor,
              titleTextStyle: CupertinoTheme.of(context)
                  .textTheme
                  .navTitleTextStyle
                  .copyWith(color: CupertinoColors.black),
              textTheme: Theme.of(context).textTheme.copyWith(
                  bodyText1: Theme.of(context)
                      .textTheme
                      .bodyText1!
                      .copyWith(color: CupertinoColors.black),
                  subtitle1: Theme.of(context)
                      .textTheme
                      .subtitle1!
                      .copyWith(color: CupertinoColors.black),
                  subtitle2: Theme.of(context).textTheme.subtitle2!.copyWith(
                      color: CupertinoTheme.of(context)
                          .textTheme
                          .tabLabelTextStyle
                          .color),
                  headline6:
                      Theme.of(context).textTheme.headline6!.copyWith(fontWeight: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle.fontWeight, color: (Platform.isIOS || Platform.isMacOS) ? CupertinoColors.black : Theme.of(context).textTheme.subtitle1!.color)),
              toolbarTextStyle: CupertinoTheme.of(context).textTheme.actionTextStyle)),
      dark: ThemeData.dark().copyWith(
          brightness: Brightness.dark,
          //backgroundColor: Theme.of(context).scaffoldBackgroundColor,
          primaryColor: (Platform.isIOS || Platform.isMacOS)
              ? CupertinoTheme.of(context).primaryColor
              : Theme.of(context).primaryColor,
          dividerColor: CupertinoColors.inactiveGray,
          scaffoldBackgroundColor: CupertinoColors.black,
          cardColor: CupertinoColors.darkBackgroundGray,
          textTheme: Theme.of(context).textTheme.copyWith(
              bodyText1: Theme.of(context)
                  .textTheme
                  .bodyText1!
                  .copyWith(color: CupertinoColors.white),
              subtitle1: Theme.of(context)
                  .textTheme
                  .subtitle1!
                  .copyWith(color: CupertinoColors.white),
              subtitle2: Theme.of(context).textTheme.subtitle2!.copyWith(
                  color: CupertinoTheme.of(context)
                      .textTheme
                      .tabLabelTextStyle
                      .color),
              headline6: Theme.of(context).textTheme.headline6!.copyWith(
                  fontWeight: CupertinoTheme.of(context)
                      .textTheme
                      .navLargeTitleTextStyle
                      .fontWeight,
                  color: (Platform.isIOS || Platform.isMacOS)
                      ? CupertinoColors.white
                      : Theme.of(context).textTheme.subtitle1!.color),
              headline4: Theme.of(context).textTheme.headline4!.copyWith(
                  fontWeight: CupertinoTheme.of(context)
                      .textTheme
                      .navLargeTitleTextStyle
                      .fontWeight,
                  color: (Platform.isIOS || Platform.isMacOS)
                      ? CupertinoColors.white
                      : Theme.of(context).textTheme.subtitle1!.color)),
          appBarTheme: Theme.of(context)
              .appBarTheme
              .copyWith(backgroundColor: CupertinoTheme.of(context).barBackgroundColor, titleTextStyle: CupertinoTheme.of(context).textTheme.navTitleTextStyle.copyWith(color: CupertinoColors.white), textTheme: Theme.of(context).textTheme.copyWith(bodyText1: Theme.of(context).textTheme.bodyText1!.copyWith(color: CupertinoColors.white), subtitle1: Theme.of(context).textTheme.subtitle1!.copyWith(color: CupertinoColors.white), subtitle2: Theme.of(context).textTheme.subtitle2!.copyWith(color: CupertinoTheme.of(context).textTheme.tabLabelTextStyle.color), headline6: Theme.of(context).textTheme.headline6!.copyWith(fontWeight: CupertinoTheme.of(context).textTheme.navLargeTitleTextStyle.fontWeight, color: (Platform.isIOS || Platform.isMacOS) ? CupertinoColors.white : Theme.of(context).textTheme.subtitle1!.color)), toolbarTextStyle: CupertinoTheme.of(context).textTheme.actionTextStyle)),
      initial: AdaptiveThemeMode.dark,
      builder: (theme, darkTheme) => MaterialApp(
        title: 'Flutter',
        theme: theme,
        darkTheme: darkTheme,
        home: LoginScreen(),
      ),
    );
  }

iOS Keyboard Appearance does not switch automatically under system settings

Describe the bug
When a text input is focused and dark mode is on/off in system settings, the keyboard appearance does not switch immediately. Instead, it only takes effect when dismiss the keyboard or focus on other text input.

To Reproduce
Steps to reproduce the behavior:

  1. Set the theme mode to system
  2. Create a text field widget
  3. Focus a text field widget
  4. Open Control Center, enable or disable dark mode (or go to settings > displays to switch dark mode on/off)
  5. Observe the keyboard appearance changes

Expected behavior
Under system mode, the keyboard appearance should switch dynamically

Screenshots

d3e456c3-2d0d-4915-9de1-30f162d8018c.mp4

Desktop (please complete the following information):
N/A

Smartphone (please complete the following information):

  • Device: iPhone 13 Pro Max
  • OS: iOS 17.1.1 (or any os is 13 or later)

Additional context
Add any other context about the problem here.

Check whether .system is light or dark

Is your feature request related to a problem? Please describe.
I'm initializing AdaptiveTheme() with initial: AdaptiveThemeMode.system, for best user experience. But for later ui logic like picking the light or dark logo I can't know if the system is light or dark.

Describe the solution you'd like
I would like to do something like AdaptiveTheme.of(context).mode.isSystem == AdaptiveThemeMode.light to check what system is currently. But both checks always return false.

Unexpected behavior with go_router

When adaptive_theme is used with go_router, and the theme changes, the router is re-initialized and returns to the default route.

Here is my root app in main.dart.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
      light: MyTheme.buildTheme(Brightness.light),
      dark: MyTheme.buildTheme(Brightness.dark),
      debugShowFloatingThemeButton: true,
      initial: AdaptiveThemeMode.system,
      builder: (theme, darkTheme) => MaterialApp.router(
        title: 'Project Snowcone',
        routerConfig: MyRouter.createRouter(),
        theme: theme,
        darkTheme: darkTheme,
      ),
    );
  }
}

Everything work fine before integrating go_router and widgets would update dynamically on theme change.

getting current theme return null

using AdaptiveTheme.getThemeMode() or AdaptiveTheme.of(context).mode.isLight and AdaptiveTheme.of(context).mode.isDark return null when theme in not persisted

Change Android Navigation Bar Color on System Dark Mode toggle

When using AdaptiveTheme.of(context).modeChangeNotifier.addListener, I can change my android's navigation bar color like this:

AdaptiveTheme.of(context).modeChangeNotifier.addListener(() async {
      //This gets the system's platform brightness.
      final platformBrightness = MediaQuery.of(context).platformBrightness;

      final themeMode = AdaptiveTheme.of(context).mode;
      late Color color;
      late Brightness brightness;

      switch (themeMode) {
        case AdaptiveThemeMode.light:
          color = Colors.white;
          brightness = Brightness.dark;
          break;
        case AdaptiveThemeMode.dark:
          color = Colors.black;
          brightness = Brightness.light;
          break;
        case AdaptiveThemeMode.system:
          color = (platformBrightness == Brightness.dark)
              ? Colors.black
              : Colors.white;
          brightness = (platformBrightness == Brightness.dark)
              ? Brightness.light
              : Brightness.dark;
          break;
        default:
          break;
      }

      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
          systemNavigationBarColor: color,
          systemNavigationBarIconBrightness: brightness));
});

However, the navigation bar color does not change when I toggle dark mode from my Notification Centre. I tried finding a way to listen for platform brightness here by using WidgetsBinding.instance.handlePlatformBrightnessChanged();, but this would disable the dynamic theming of the app provided in your package (As I realised that I am probably overriding your code).

Is there a way I can change the navigation bar color, when toggling dark mode from notification centre?

Example (Gif was too large to show here, sorry)

Restart App color disappeared

Describe the bug
Restart the app and customize the color to disappear.

To Reproduce
Steps to reproduce the behavior:
1.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final savedThemeMode = await AdaptiveTheme.getThemeMode();
  runApp(MyApp(savedThemeMode: savedThemeMode));
}
class MyApp extends StatelessWidget {
  final AdaptiveThemeMode? savedThemeMode;
  const MyApp({super.key, this.savedThemeMode});
  ...
}

...

ElevatedButton(
  onPressed: () {
    AdaptiveTheme.of(context).setTheme(
      light: ThemeData(
        useMaterial3: true,
        brightness: Brightness.light,
        colorSchemeSeed: Colors.green,
      ),
      dark: ThemeData(
        useMaterial3: true,
        brightness: Brightness.dark,
        colorSchemeSeed: Colors.green,
      ),
    );
  },
  child: const Text('Green'),
),
  1. Restart App
  2. colorSchemeSeed: Colors.green, not work

Additional context
When I changed the theme, I changed the color, but when I restarted the app, I found that the set color had disappeared.
Through the README, I found that I can use isDefault when setting the theme, but I did not find this parameter in the latest version. How can I save the color I set, and when restarting the APP, I hope to display the color I set.
Thanks a lot.

AdaptiveTheme.of(context).setTheme is not working

I am setting both Light and Dark Theme with initial Primary Color. Later in Settings screen, i am using setTheme() to change entire color theme with other primary color. But it is not changing to new color. I have checked in both iOS and Android.

void setApplicationColorTheme(
    {required BuildContext context, required Color primaryAppColor}) {
  print("primaryAppColor is $primaryAppColor");
  AdaptiveTheme.of(context).setTheme(
      light: getLightThemeData(primaryAppColor: primaryAppColor),
      dark: getDarkThemeData(primaryAppColor: primaryAppColor),
      notify: true);
}

Expected behavior
It should change entire app theme with new primary color.

Please suggest me to fix this issue.

Update Readme

In readme there is accentColor used in ThemeData. As i know accentColor does not exist in ThemeData.

[AdaptiveTheme] builder parameters

Describe the bug
The builder functions gives 2 parameters, both are Themes. According to the documentation and the examples like:
builder: (theme, darkTheme) => MaterialApp(... the first one is always Light Theme and the second one is always Dark Theme. But its currently not working that way, both parameters are sending the same twice. When the app is on Light mode both params are Light Theme, and when the app is in dark mode, both params are Dark Theme.

To Reproduce
Steps to reproduce the behavior:

  1. Create an AdaptiveTheme with dark and light themes
  2. At the AdaptiveTheme's "builder" function call a print with both theme params and check they are the same at both app modes.

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
image
image

Desktop (please complete the following information):
Doesnt matter

Smartphone (please complete the following information):
Doesnt matter

Additional context
Add any other context about the problem here.

Custom font not working

When i set custom font for MaterialApp not working, in this situation AdaptiveTheme is parent of MaterialApp
When i remove AdaptiveTheme custom font work as well

Adaptive_Theme on windows has problem with shared_preferences

Describe the bug
I try to use adaptive_theme first time with windows and ran into following issue:

To Reproduce
Steps to reproduce the behavior:

  1. add adaptive_theme to project in version ^3.0.0
  2. run the app with windows as target.

Expected behavior
The app starts up without error.

Screenshots

[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: 'package:shared_preferences/shared_preferences.dart': Failed assertion: line 169 pos 14: 'key.startsWith(_prefix)': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
#2      SharedPreferences._getSharedPreferencesMap (package:shared_preferences/shared_preferences.dart:169:14)
<asynchronous suspension>
#3      SharedPreferences.getInstance (package:shared_preferences/shared_preferences.dart:33:13)
<asynchronous suspension>
#4      ThemePreferences.fromPrefs (package:adaptive_theme/src/adaptive_theme_preferences.dart:62:21)
<asynchronous suspension>
#5      AdaptiveTheme.getThemeMode (package:adaptive_theme/src/adaptive_theme.dart:91:13)
<asynchronous suspension>
==> #6      main (package:spaceup_ui/main.dart:18:26) <==
<asynchronous suspension>

That's following line in my code
image

I also use shared_prefences_settings. Might this be an issue? On Linux, Android and web there is no issue.

Theme resetting at app launch

UPDATE:

Just tried it on my real android device and there it works perfectly.
Not sure why it doesn't work in the simulator.

Describe the bug
I have implemented the solution almost identical to the docs, but on a hot restart, the builder method runs twice, where on the first run has the correct theme which is set in the initial prop, but on the second run it's the light theme.
On a hot restart I can actually see the colors changing from dark to light in a split second.

Here is the first part of my root build method:
I'm using the GetX package, hence the GetMaterialApp method.

@override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
        light: lightTheme,
        dark: darkTheme,
        initial: AdaptiveThemeMode.dark,
        builder: (light, dark) {
          print('light: ${light.scaffoldBackgroundColor}');
          print('dark: ${dark.scaffoldBackgroundColor}');
          return GetMaterialApp(
            navigatorKey: navigatorKey,
            locale: const Locale('sv', 'SE'),
            theme: light,
            darkTheme: dark,

Here is the output from my debug console:

flutter: light: MaterialColor(primary value: Color(0xff4caf50))
flutter: dark: MaterialColor(primary value: Color(0xff4caf50))
[GETX] Instance "GetMaterialController" has been created
[GETX] Instance "GetMaterialController" has been initialized
[GETX] Redirect to null
[GETX] GOING TO ROUTE /home
[GETX] Instance "HomeController" has been created
[GETX] Instance "HomeController" has been initialized
flutter: light: MaterialColor(primary value: Color(0xff673ab7))
flutter: dark: MaterialColor(primary value: Color(0xff673ab7))

As you can see the print in the build method runs twice with different values, where the first values represent the color in the dark mode, and the second time it's the values in the light mode.

Expected behavior
I expect the theme set in the initial prop to be the theme in use.

Smartphone (please complete the following information):

  • Device: iOS Simulator
  • OS: iOS 15.0
  • Version iPhone 13 Pro

Runtime error

Trying to run the example application on an Android phone, I am getting the following error:

"package:flutter/src/ material/theme_data.dart': Failed assertion: line 346 pos 12: colorScheme?.brightness == null || brightness I| colorScheme!.brightness = brightness': is not true. See also: https://flutter.dev/docs /testing/errorS == null

To Reproduce
Just download the package from github, and run [flutter create .] follow by [flutter run]

Screenshotsimage

Smartphone (please complete the following information):

  • Device: Samsung Galaxy A50
  • OS: 11

Add custom mode

hello
Is there a way to add a third mode ?

For instance i want a dark blue background as a third option
I can i do that if possible

If not it will be very cool to have such an option

get theme and get darkTheme returns the same theme dependend on mode

Retrieving the ThemeData with get theme and get darkTheme will return not the expected themes of light theme and dark theme, instead both return the "active" theme.

To Reproduce
Compare AdaptiveTheme.of(context).theme with AdaptiveTheme.of(context).darkTheme;.

Expected behavior
theme returns the light theme and darkTheme returns the dark theme.

Responsible Code
from adaptive_theme.dart, which is cousing this behaviour:

  @override
  ThemeData get theme => preferences.mode.isDark ? _darkTheme : _theme;

  @override
  ThemeData get darkTheme => preferences.mode.isLight ? _theme : _darkTheme;

Dynamically switching based on macOS not working

For some reason, if I switch the macOS theme from light to dark (or vice versa) in System Settings, my macOS flutter app doesn't dynamically switch.

If I'm running the app from VS Code and manually reload (or do a full restart), then it will use whatever the system is at that time. However, if I switch the operating system setting after starting the app, it doesn't dynamically change.

Is the expected behaviour that the new theme is only re-applied after app restart?

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
        light: ThemeData(brightness: Brightness.light, primarySwatch: Colors.red),
        dark: ThemeData(brightness: Brightness.dark, primarySwatch: Colors.red),
        initial: AdaptiveThemeMode.system,
        builder: (theme, darkTheme) {
          return MaterialApp(theme: theme, darkTheme: darkTheme, home: Scaffold(body: Text('hi there')));
        });
  }
}

Steps to reproduce the behavior:

  1. Create a macOS flutter app
  2. Add adaptive_theme to pubspec
  3. Run the app with the code above
  4. Switch the operating system theme
  5. Observe that the flutter app theme doesn't change dynamically
  • OS: macOS Catalina 10.15.7
  • Adaptive_theme: 2.2.0

Flashing/Incorrect bevior on theme change in flutter web deployment on mobile devices

Describe the bug
As discussed in other issues we can prevent a flashing bevior on Theme changes and set initial values when passing it directly
into the AdaptiveThemeWidget when passing an savedThemeMode before runApp.
However, I am currently experiencing a flash in the browser status bar and browser bar when switchting from light to dark mode and vice versa.
There is no flash when I build for Android
There is no flash when I build for Web and access with DesktopBrowser (tested with Chrome and Firefox)

THERE IS A FLASH When building for web and accessing through a Browser on a mobile device! (Tested with three phones, two of them recent Android phones and one recent Iphone)
It is very hard to reproduce and to demonstrate because of this but for demonstration purpose I post my sample site where it is deployed. You need to open this using your mobile phones browser Test Site. Just hit the theme change button and should see the incorrect bevior.

reproduction_video.mp4

To Reproduce
Steps to reproduce the behavior:

  1. Go to Test Site with your phones browser
  2. Click on the theme change button
    3 See the flash in the status bar and browser bar.

Expected behavior
No flash and same expeierence as on a desktop browser

Smartphone (please complete the following information):
1 Recent Iphone using browser (no data because not my device)
1 Android Phone from 2021 using browser (no data because not my device)
1 Android Phone Huawei P30 Pro using browser (my phone)

Additional context
I am using adaptive_theme: ^3.3.0

This is the code of used main.dart file

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final savedThemeMode = await AdaptiveTheme.getThemeMode();
  runApp(MyApp(savedThemeMode: savedThemeMode));
}

class MyApp extends StatelessWidget {
  final AdaptiveThemeMode? savedThemeMode;
  const MyApp({super.key, this.savedThemeMode});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return AdaptiveTheme(
        light: ThemeData(
          colorSchemeSeed: Colors.green,
          brightness: Brightness.light,
          appBarTheme: const AppBarTheme(
              systemOverlayStyle: SystemUiOverlayStyle(
                  systemNavigationBarColor: Colors.green,
                  systemNavigationBarIconBrightness: Brightness.dark)),
          useMaterial3: true,
        ),
        dark: ThemeData(
          colorSchemeSeed: Colors.green,
          brightness: Brightness.dark,
          appBarTheme: const AppBarTheme(
              systemOverlayStyle: SystemUiOverlayStyle(
                  systemNavigationBarColor: Colors.green,
                  systemNavigationBarIconBrightness: Brightness.light)),
          useMaterial3: true,
        ),
        debugShowFloatingThemeButton: true,
        initial: savedThemeMode ?? AdaptiveThemeMode.light,
        builder: (theme, darkTheme) => MaterialApp(
              title: 'FoodSnapAI',
              theme: theme,
              darkTheme: darkTheme,
              home:
                  const MyHomePage(title: 'FoodSnapAI page - work in progress'),
            ));
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  void initState() {
    super.initState();
  }

  void _toggleDarkMode() {
    final manager = AdaptiveTheme.of(context);
    if (manager.mode.isLight) {
      manager.setDark();
    } else {
      manager.setLight();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.primaryContainer,
        title: Text(
          widget.title,
        ),
        actions: [
          Container(
              margin: const EdgeInsets.only(right: 20.0),
              child: IconButton(
                  onPressed: _toggleDarkMode,
                  icon: Icon(AdaptiveTheme.of(context).mode.isDark
                      ? Icons.dark_mode
                      : Icons.dark_mode_outlined)))
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            BuildingCard(),
          ],
        ),
      ),
    );
  }
}

Toggle between dark and light theme only

Long time ago there was an issue regarding this - #14, so this is kinda a resurrection of that. ๐Ÿ˜„

You already mentioned a solution there. I looked up the code, and it should be fairly simple to implement this with one optional parameter "useSystem" to toggleThemeMode method. I wanted to sumbit a PR, but found myself in dilemma what is the cleanest way to write this down, so I decided to ask you if you could do it. ๐Ÿ˜€

Btw, thank you for this package. It's awesome! ๐Ÿ‘Œ

addListener() - Null check operator used on a null value

As title, using

 AdaptiveTheme.of(context).modeChangeNotifier.addListener(() {
        // set status bar here.
        });

gives the error "Null check operator used on a null value".

I've tried putting in inside initState and AdaptiveTheme builder, none of it worked.

In documentation, there aren't any info on where to put this method.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.