0

我正在使用提供程序来管理暗模式和亮模式以及共享首选项来保存它。我已成功保存所选主题,但无法根据选择更改抽屉 ListTile 中的图标和文本。

主题飞镖:

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

我希望图标如何更改,但此代码不起作用。

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",
                          ),
                        ),
                ),

这 ?和:逻辑我想在这里用于选定的主题,比如如果它的暗模式,那么图标应该是太阳,它应该说光模式和光模式的交替。

主文件代码:

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

主页文件:

@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();
  }
4

2 回答 2

1

我曾经ThemeMode检查过模式。

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",
                        ),
                      ),
              ),
            ],
          );
        },
      ),
    );
  }
}
于 2022-02-18T15:08:42.180 回答
0

对于图标,而不是做

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

您将需要订阅提供程序。您可以使用与您相同的方式onTap访问提供程序:

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

请注意listen: true,您的小部件订阅您的ThemeNotifier并在每次通知其侦听器时重新构建。

于 2022-02-18T14:13:33.250 回答