Flutter:从另一个小部件更改主题亮度

时间:2019-12-25 03:06:28

标签: flutter dart

我有2个屏幕,分别是登录首页,以学习在MaterialApp动态中更改亮度。我使用2个软件包HiveProvider Packages帮助我处理案件。

一切都很好,我可以在主屏幕中更改值开关,但问题是MaterialApp中的值未更改。我只看到开关更改,但ThemeData没有更改。如果我热重启,它就变了。

我弄错了什么?

用户提供商

class UserProvider with ChangeNotifier {
  final String boxName = "user_box";
  Future<void> changeThemeApp({@required UserModelHive userModelHive}) async {
    final hiveBox = Hive.box(boxName);
    final valueBox = userModelHive;
    await hiveBox.put("userSession", valueBox);
    notifyListeners();
  }
}

MyApp窗口小部件

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final appDir = await pathProvider.getApplicationDocumentsDirectory();
  Hive.init(appDir.path);
  Hive.registerAdapter(UserModelHiveAdapter(), 0);
  await Hive.openBox('user_box');
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final userBox = Hive.box('user_box');
    if (userBox.isEmpty) {
      return MaterialAppCustom(home: LoginProvider());
    } else {
      final UserModelHive userModelHive = userBox.get("userSession");
      print(userModelHive.isDarkMode.toString());
      return MaterialAppCustom(
        brightness:
            userModelHive.isDarkMode ? Brightness.dark : Brightness.light,
        home: HomeScreen(),
      );
    }
  }
}

class MaterialAppCustom extends StatelessWidget {
  final Widget home;
  final Brightness brightness;
  MaterialAppCustom({@required this.home, this.brightness});
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => UserProvider(),
      child: MaterialApp(
        home: home,
        theme: ThemeData(brightness: brightness),
        routes: {
          LoginProvider.routeNamed: (ctx) => LoginProvider(),
          HomeScreen.routeNamed: (ctx) => HomeScreen(),
        },
      ),
    );
  }
}

主屏幕

class HomeScreen extends StatelessWidget {
  static const routeNamed = "home-screen";
  @override
  Widget build(BuildContext context) {
    final userProvider = Provider.of<UserProvider>(context);
    final UserModelHive userModelHive = Hive.box('user_box').get("userSession");
    return Scaffold(
      body: AppBar(
        actions: <Widget>[
          Switch(
            value: userModelHive.isDarkMode,
            onChanged: (value) {
              return userProvider.changeThemeApp(
                userModelHive: UserModelHive()
                  ..id = userModelHive.id
                  ..name = userModelHive.name
                  ..isDarkMode = value,
              );
            },
          ),
        ],
      ),
    );
  }
}

My Gif

1 个答案:

答案 0 :(得分:1)

  1. WatchBoxBuilder小部件包装WatchBoxBuilder(在蜂巢包装中)。
  2. 您应该使用枚举,整数或字符串值映射主题。
  3. 有一个配置单元,您可以在其中保存主题的值。
  4. 将该框提供给环绕在Material Widget周围的WatchBoxBuilder
  5. 现在,只要在蜂巢框中更改主题的值,您的WatchBoxBuilder就会重建,并且主题将从应用程序的任何部分更改。

无论何时在小部件树中使用配置单元,都应仅通过{{1}}读取值。它具有重建小部件的功能,以便可以使用新值。

我希望这会有所帮助,如有任何疑问,请发表评论。