繁体   English   中英

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

[英]Flutter : Change Theme Brightness from another Widget

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

我的应用小工具

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

我的GIF

  1. WatchBoxBuilder小部件包装您的MaterialApp (它在 hive 包中)。
  2. 您应该使用 enum、int 或 string 值映射您的主题。
  3. 有一个 Hive 框,您可以在其中保存主题的值。
  4. 将该框交给包裹在 Material Widget 周围的WatchBoxBuilder
  5. 现在,无论何时在 hive 框中更改 theme 的值,您的WatchBoxBuilder都会重建,并且您的主题将从应用程序的任何部分更改。

每当您在小部件树中使用 hive 时,您应该只通过WatchBoxBuilder读取值。 它有能力重建您的小部件,以便它可以使用新值。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM