Home > Net >  How to change the icon according to the theme in flutter
How to change the icon according to the theme in flutter

Time:02-19

I'm using provider for managing the dark and light mode along with shared preferences to save it. I have successfully managed to save the selected theme but I'm unable to change the icons and the text in ListTile of my drawer according to the selection.

Theme.dart:

class ThemeProvider extends ChangeNotifier {
  late ThemeData _selectedTheme;
  late Typography defaultTypography;
  late SharedPreferences prefs;

  ThemeData dark = ThemeData.dark().copyWith();

  ThemeData light = ThemeData.light().copyWith();

  ThemeProvider(bool darkThemeOn) {
    _selectedTheme = darkThemeOn ? dark : light;
  }

  Future<void> swapTheme() async {
    prefs = await SharedPreferences.getInstance();

    if (_selectedTheme == dark) {
      _selectedTheme = light;
      await prefs.setBool("darkTheme", false);
    } else {
      _selectedTheme = dark;
      await prefs.setBool("darkTheme", true);
    }

    notifyListeners();
  }

  ThemeData getTheme() => _selectedTheme;
}

How I want the icons to change but this code isnt working.

ListTile(
                  onTap: () {
                    Provider.of<ThemeProvider>(context, listen: false)
                        .swapTheme();
                  },
                  leading: Icon(MyApp.themeNotifier.value == ThemeMode.light
                      ? Icons.dark_mode
                      : Icons.light_mode),
                  title: MyApp.themeNotifier.value == ThemeMode.light
                      ? Text(
                          "Dark Mode",
                          style: TextStyle(
                            fontFamily: "San Francisco",
                          ),
                        )
                      : Text(
                          "Light Mode",
                          style: TextStyle(
                            fontFamily: "San Francisco",
                          ),
                        ),
                ),

The ? and : logic I want here to be used on the selected theme like if its dark mode then the icon should be sun and it should say light mode and alternate of that for light mode.

Main file code:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  SharedPreferences.getInstance().then((prefs) {
    var isDarkTheme = prefs.getBool("darkTheme") ?? false;
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
    // await MobileAds.instance.initialize();
    return runApp(
      ChangeNotifierProvider<ThemeProvider>(
        child: MyApp(),
        create: (BuildContext context) {
          return ThemeProvider(isDarkTheme);
        },
      ),
    );
  });
}

class MyApp extends StatelessWidget {
  static final ValueNotifier<ThemeMode> themeNotifier =
      ValueNotifier(ThemeMode.light);
  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<ThemeMode>(
        valueListenable: themeNotifier,
        builder: (_, ThemeMode currentMode, __) {
          return Consumer<ThemeProvider>(builder: (context, value, child) {
            return ChangeNotifierProvider<AppProvider>(
              create: (context) => AppProvider(),
              child: MaterialApp(
                title: 'Buddies',
                darkTheme: ThemeData.dark(),
                theme: value.getTheme(),
                themeMode: currentMode,
                debugShowCheckedModeBanner: false,
                home: StreamBuilder(
                    stream: FirebaseAuth.instance.authStateChanges(),
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        return HomePage(
                          showPop: false,
                        );
                      }
                      return LoginScreen();
                    }),
              ),
            );
          });
        });
  }
}

Homefile :

@override
  Widget build(BuildContext context) {
    Future.delayed(Duration.zero, () => showDialogIfFirstLoaded(context));
    return AdvancedDrawer(
      backdropColor: Theme.of(context).primaryColor,
      controller: _advancedDrawerController,
      animationCurve: Curves.easeInOut,
      animationDuration: const Duration(milliseconds: 300),
      animateChildDecoration: true,
      rtlOpening: false,
      disabledGestures: false,
      childDecoration: const BoxDecoration(
        borderRadius: const BorderRadius.all(Radius.circular(16)),
      ),
      drawer: SafeArea(
        child: Container(
          color: Theme.of(context).primaryColor,
          child: ListTileTheme(
            textColor: Colors.white,
            iconColor: Colors.white,
            child: Column(
              mainAxisSize: MainAxisSize.max,
              children: [
                StreamBuilder(
                  stream: FirebaseFirestore.instance
                      .collection("users")
                      .doc(currentUserUid)
                      .snapshots(),
                  builder: (context,
                      AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>>
                          snapshot) {
                    if (snapshot.connectionState == ConnectionState.waiting) {
                      return Center(
                        child: CircularProgressIndicator(),
                      );
                    }
                    if (!snapshot.hasData) {
                      return Center(
                        child: CircularProgressIndicator(),
                      );
                    }
                    return Container(
                      width: 128.0,
                      height: 128.0,
                      margin: const EdgeInsets.only(
                        top: 24.0,
                        bottom: 64.0,
                      ),
                      child: ClipOval(
                        child: SizedBox.fromSize(
                          size: Size.fromRadius(48), // Image radius
                          child: Image.network(snapshot.data!.get("image"),
                              fit: BoxFit.fill),
                        ),
                      ),
                    );
                  },
                ),
                ListTile(
                  onTap: () {
                    Provider.of<ThemeProvider>(context, listen: false)
                        .swapTheme();
                  },
                  leading: Icon(value.mode == ThemeMode.light
                      ? Icons.dark_mode
                      : Icons.light_mode),
                  title: value.mode == ThemeMode.light
                      ? Text(
                          "Dark Mode",
                          style: TextStyle(
                            fontFamily: "San Francisco",
                          ),
                        )
                      : Text(
                          "Light Mode",
                          style: TextStyle(
                            fontFamily: "San Francisco",
                          ),
                        ),
                ),
                // ListTile(
                //   onTap: () {
                //     Provider.of<ThemeProvider>(context, listen: false)
                //         .swapTheme();
                //   },
                //   leading: Icon(MyApp.themeNotifier.value == ThemeMode.light
                //       ? Icons.dark_mode
                //       : Icons.light_mode),
                //   title: MyApp.themeNotifier.value == ThemeMode.light
                //       ? Text(
                //           "Dark Mode",
                //           style: TextStyle(
                //             fontFamily: "San Francisco",
                //           ),
                //         )
                //       : Text(
                //           "Light Mode",
                //           style: TextStyle(
                //             fontFamily: "San Francisco",
                //           ),
                //         ),
                // ),
                ListTile(
                  onTap: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (ctx) => HomePage(
                          showPop: false,
                        ),
                      ),
                    );
                  },
                  leading: Icon(Icons.home),
                  title: Text(
                    'Home',
                    style: TextStyle(
                      fontFamily: "San Francisco",
                    ),
                  ),
                ),
                ListTile(
                  onTap: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (ctx) => ProfilePage(),
                      ),
                    );
                  },
                  leading: Icon(Icons.person),
                  title: Text(
                    'Profile',
                    style: TextStyle(
                      fontFamily: "San Francisco",
                    ),
                  ),
                ),
                ListTile(
                  onTap: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (ctx) => ContactUs(),
                      ),
                    );
                  },
                  leading: Icon(Icons.email),
                  title: Text(
                    'Contact us',
                    style: TextStyle(
                      fontFamily: "San Francisco",
                    ),
                  ),
                ),
                ListTile(
                  onTap: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (ctx) => ReportBug(),
                      ),
                    );
                  },
                  leading: Icon(Icons.bug_report),
                  title: Text(
                    'Report a bug',
                    style: TextStyle(
                      fontFamily: "San Francisco",
                    ),
                  ),
                ),
                ListTile(
                  onTap: () async {
                    await FirebaseAuth.instance.signOut();
                    Navigator.of(context).pushReplacement(
                      MaterialPageRoute(
                        builder: (ctx) => LoginScreen(),
                      ),
                    );
                  },
                  leading: Icon(Icons.logout),
                  title: Text(
                    'Logout',
                    style: TextStyle(
                      fontFamily: "San Francisco",
                    ),
                  ),
                ),
                Spacer(),
                DefaultTextStyle(
                  style: TextStyle(
                    fontSize: 12,
                  ),
                  child: GestureDetector(
                    onTap: () {
                      _launchURL(
                          "https://buddiesapp.co/policies/privacy-policy");
                    },
                    child: Container(
                      margin: const EdgeInsets.symmetric(
                        vertical: 16.0,
                      ),
                      child: Text(
                        'Privacy Policy',
                        style: TextStyle(
                            fontFamily: "San Francisco",
                            fontSize: 15,
                            decoration: TextDecoration.underline),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
      child: CheckDealScreen(
        home: Scaffold(
          appBar: AppBar(
            centerTitle: true,
            title: const Text(
              "Buddies",
              style: TextStyle(
                fontFamily: "San Francisco",
              ),
            ),
            automaticallyImplyLeading: false,
            leading: IconButton(
              onPressed: _handleMenuButtonPressed,
              icon: ValueListenableBuilder<AdvancedDrawerValue>(
                valueListenable: _advancedDrawerController,
                builder: (_, value, __) {
                  return AnimatedSwitcher(
                    duration: Duration(milliseconds: 250),
                    child: Icon(
                      value.visible ? Icons.clear : Icons.menu,
                      key: ValueKey<bool>(value.visible),
                    ),
                  );
                },
              ),
            ),
            backgroundColor: Theme.of(context).primaryColor,
          ),
          body: Consumer<ThemeProvider>(
            builder: (context, value, child) {
              return currentUserUid.isEmpty
                  ? Center(
                      child: CircularProgressIndicator(),
                    )
                  : StreamBuilder(
                      stream: FirebaseFirestore.instance
                          .collection("users")
                          .doc(currentUserUid)
                          .snapshots(),
                      builder: (context,
                          AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>>
                              snapshot) {
                        if (snapshot.connectionState ==
                            ConnectionState.waiting) {
                          return Center(
                            child: CircularProgressIndicator(),
                          );
                        }
                        if (!snapshot.hasData) {
                          return Center(
                            child: CircularProgressIndicator(),
                          );
                        }
                        return Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 12.0),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Image.asset(
                                "assets/splashnew.png",
                                scale: 5,
                              ),
                              SizedBox(
                                height: 40,
                              ),
                              Container(
                                width: double.infinity,
                                height: 50,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(25),
                                  color: Theme.of(context).primaryColor,
                                ),
                                child: MaterialButton(
                                  child: Column(
                                    children: [
                                      SizedBox(
                                        height: 6.0,
                                      ),
                                      Text(
                                        "Meet & Bom",
                                        style: const TextStyle(
                                          color: Colors.white,
                                          fontFamily: "San Francisco",
                                          fontStyle: FontStyle.normal,
                                          fontSize: 18,
                                        ),
                                      ),
                                      Text(
                                        "Get 50 points for bomming",
                                        style: const TextStyle(
                                          fontFamily: "San Francisco",
                                          fontStyle: FontStyle.normal,
                                          fontSize: 12,
                                        ),
                                      ),
                                    ],
                                  ),
                                  onPressed: () {
                                    Navigator.of(context).push(
                                      MaterialPageRoute(
                                        builder: (ctx) => const DonateSnus(),
                                      ),
                                    );
                                  },
                                ),
                              ),
                              const SizedBox(
                                height: 24.0,
                              ),
                              Container(
                                width: double.infinity,
                                height: 50,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(25),
                                  color: Theme.of(context).primaryColor,
                                ),
                                child: MaterialButton(
                                  child: Column(
                                    children: [
                                      SizedBox(
                                        height: 6.0,
                                      ),
                                      Text(
                                        "Meet a Buddy",
                                        style: const TextStyle(
                                          color: Colors.white,
                                          fontFamily: "San Francisco",
                                          fontStyle: FontStyle.normal,
                                          fontSize: 18,
                                        ),
                                      ),
                                      Text(
                                        "You'll need 10 points",
                                        style: const TextStyle(
                                          fontFamily: "San Francisco",
                                          fontStyle: FontStyle.normal,
                                          fontSize: 12,
                                        ),
                                      ),
                                    ],
                                  ),
                                  onPressed: () {
                                    if (snapshot.data!.get("points") >= 10) {
                                      Navigator.of(context).push(
                                        MaterialPageRoute(
                                          builder: (ctx) => INeedSnus(),
                                        ),
                                      );
                                    } else {
                                      ScaffoldMessenger.of(context)
                                          .showSnackBar(SnackBar(
                                        content: Text(
                                          "You need 10 points to send request ",
                                          style: TextStyle(
                                            fontFamily: "San Francisco",
                                          ),
                                        ),
                                      ));
                                    }
                                  },
                                ),
                              ),
                              const SizedBox(
                                height: 24.0,
                              ),
                              isLoaded
                                  ? Center(
                                      child: CircularProgressIndicator(),
                                    )
                                  : Container(
                                      width: double.infinity,
                                      height: 50,
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(25),
                                        color: Theme.of(context).primaryColor,
                                      ),
                                      child: MaterialButton(
                                        child: Column(
                                          children: [
                                            SizedBox(
                                              height: 6.0,
                                            ),
                                            Text(
                                              "Watch ads - Get Points ",
                                              style: const TextStyle(
                                                color: Colors.white,
                                                fontFamily: "San Francisco",
                                                fontStyle: FontStyle.normal,
                                                fontSize: 18,
                                              ),
                                            ),
                                            Text(
                                              "Get 2.5 points",
                                              style: const TextStyle(
                                                fontFamily: "San Francisco",
                                                fontStyle: FontStyle.normal,
                                                fontSize: 12,
                                              ),
                                            ),
                                          ],
                                        ),
                                        onPressed: () {
                                          loadAd(snapshot.data!.get("points"));
                                          // print(DateTime.now().toLocal());
                                        },
                                      ),
                                    ),
                              const SizedBox(
                                height: 24.0,
                              ),
                              Container(
                                width: double.infinity,
                                height: 50,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(25),
                                  color: Theme.of(context).primaryColor,
                                ),
                                child: MaterialButton(
                                  child: Column(
                                    children: [
                                      SizedBox(
                                        height: 6.0,
                                      ),
                                      Text(
                                        "Refer a friend",
                                        style: const TextStyle(
                                          color: Colors.white,
                                          fontFamily: "San Francisco",
                                          fontStyle: FontStyle.normal,
                                          fontSize: 18,
                                        ),
                                      ),
                                      Text(
                                        "Get 5 Points",
                                        style: const TextStyle(
                                          fontFamily: "San Francisco",
                                          fontStyle: FontStyle.normal,
                                          fontSize: 12,
                                        ),
                                      ),
                                    ],
                                  ),
                                  onPressed: () {
                                    Navigator.of(context).push(
                                      MaterialPageRoute(
                                        builder: (ctx) => ReferAFriend(
                                          referCode: snapshot.data!
                                              .get("myrefercode")
                                              .toString(),
                                        ),
                                      ),
                                    );
                                  },
                                ),
                              ),
                              const SizedBox(
                                height: 24.0,
                              ),
                              Container(
                                width: 150,
                                padding: const EdgeInsets.symmetric(
                                    horizontal: 12.0),
                                height: 50,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(25),
                                  color: Theme.of(context).primaryColor,
                                ),
                                child: Row(
                                  mainAxisAlignment:
                                      MainAxisAlignment.spaceBetween,
                                  children: [
                                    Text(
                                      "Points",
                                      style: TextStyle(
                                        fontFamily: "San Francisco",
                                        fontStyle: FontStyle.normal,
                                        color: Colors.white,
                                      ),
                                    ),
                                    Text(
                                      "${snapshot.data!.get("points").toStringAsFixed(2)}",
                                      style: TextStyle(
                                        fontFamily: "San Francisco",
                                        fontStyle: FontStyle.normal,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                              const SizedBox(
                                height: 24.0,
                              ),
                            ],
                          ),
                        );
                      });
            },
          ),
        ),
      ),
    );
  }

  void _handleMenuButtonPressed() {
    _advancedDrawerController.showDrawer();
  }

CodePudding user response:

I've used ThemeMode to check the mode.

class ThemeProvider extends ChangeNotifier {
  late ThemeMode _themeMode;
  late Typography defaultTypography;
  late SharedPreferences prefs;

  ThemeData dark = ThemeData.dark().copyWith();

  ThemeData light = ThemeData.light().copyWith();

  ThemeProvider(bool darkThemeOn) {
    _themeMode = darkThemeOn ? ThemeMode.dark : ThemeMode.light;
  }

  Future<void> swapTheme() async {
    prefs = await SharedPreferences.getInstance();

    if (_themeMode == ThemeMode.light) {
      await prefs.setBool("darkTheme", false);
      _themeMode = ThemeMode.dark;
    } else {
      await prefs.setBool("darkTheme", true);
      _themeMode = ThemeMode.light;
    }
    notifyListeners();
  }

  ThemeMode get mode => _themeMode;
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  SharedPreferences.getInstance().then((prefs) {
    var isDarkTheme = prefs.getBool("darkTheme") ?? false;

    return runApp(
      ChangeNotifierProvider<ThemeProvider>(
        create: (BuildContext context) {
          return ThemeProvider(isDarkTheme);
        },
        child: const MyApp(),
      ),
    );
  });
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Consumer<ThemeProvider>(
      builder: (context, themeProvider, child) {
        return MaterialApp(
          title: 'Buddies',
          darkTheme: themeProvider.dark,
          theme: themeProvider.light,
          themeMode: themeProvider.mode,
          debugShowCheckedModeBanner: false,
          home: ThemeTester(),
        );
      },
    );
  }
}


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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Consumer<ThemeProvider>(
        builder: (context, value, child) {
          return Column(
            children: [
              ListTile(
                onTap: () {
                  Provider.of<ThemeProvider>(context, listen: false)
                      .swapTheme();
                },
                leading: Icon(value.mode == ThemeMode.light
                    ? Icons.dark_mode
                    : Icons.light_mode),
                title: value.mode == ThemeMode.light
                    ? Text(
                        "Dark Mode",
                        style: TextStyle(
                          fontFamily: "San Francisco",
                        ),
                      )
                    : Text(
                        "Light Mode",
                        style: TextStyle(
                          fontFamily: "San Francisco",
                        ),
                      ),
              ),
            ],
          );
        },
      ),
    );
  }
}

CodePudding user response:

For the icon, instead of doing

MyApp.themeNotifier.value == ThemeMode.light ? Icons.dark_mode : Icons.light_mode

You will need to subscribe to the provider. You can use the same way you did in your onTap to access the provider:

Provider.of<ThemeProvider>(context, listen: true).value == ThemeMode.light ? Icons.dark_mode : Icons.light_mode

Notice listen: true so your widget subscribes to your ThemeNotifier and rebuilds every time it notifies its listeners.

  • Related