使用Hive和Riverpod的Flutter区域

zujrkrfu  于 2022-12-05  发布在  Flutter
关注(0)|答案(1)|浏览(172)

我正在使用Hive with app_profile数据模型将应用设置存储在本地DB中,并使用riverpod调用HivedataStore(依赖注入)。问题是,当我更新本地类型的hive box时,应用需要重新启动才能生效,但如果我将主题更新为Dark,它就可以正常工作。
下面是我的代码:
main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // await AppAssets.preloadSVGs();
  final dataStore = HiveDataStore();
  await dataStore.init();
  await dataStore.createDefaultProfile(
      appProfile: AppProfile(
    onBoardingCompleted: false,
    locale: 'en',
    themeMode: ThemeModeCustomized.light,
  ));

  runApp(ProviderScope(overrides: [
    hiveDataStoreProvider.overrideWithValue(dataStore),
  ], child: const MyApp()));
}

配置单元数据存储.dart

class HiveDataStore {
  static const profileBoxName = 'appProfile';
  static const themeColor = 'themeColor';

  Future<void> init() async {
    await Hive.initFlutter();

    Hive.registerAdapter<AppProfile>(AppProfileAdapter());
    Hive.registerAdapter(ThemeModeCustomizedAdapter());

    await Hive.openBox<AppProfile>(profileBoxName);
  }

  Future<void> createDefaultProfile({
    required AppProfile appProfile,
  }) async {
    final box = Hive.box<AppProfile>(profileBoxName);
    if (box.isEmpty) {
      await box.put('0', appProfile);
    } else {
      print('box already have these Values : ${box.get(0)?.locale}');
    
    }
  }

  Future<void> updateBox({
    bool? onBoardingCompleted,
   String? locale,
    ThemeModeCustomized? themeMode,
  }) async {
    final box = Hive.box<AppProfile>(profileBoxName);
    final userProfile = box.get('0');
    final newProfile = userProfile!.copyWith(
        onBoardingCompleted: onBoardingCompleted,
        locale: locale,
        themeMode: themeMode);
    await box.put('0', newProfile);
  }

  AppProfile? appProfile() {
    final box = Hive.box<AppProfile>(profileBoxName);
    return box.get(0);
  }

  ValueListenable<Box<AppProfile>> appProfileListenable() {
    return Hive.box<AppProfile>(profileBoxName).listenable();
  }
}

final hiveDataStoreProvider = Provider<HiveDataStore>((ref) {
  throw UnimplementedError();
});

myapp.dart

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
 
    final provider = ref.watch(hiveDataStoreProvider);
    return ValueListenableBuilder(
        valueListenable: provider.appProfileListenable(),
        builder: (context, Box<AppProfile> box, __) {
          print('myapp rebuilds listenablebuilder');
          final appProfile =  box.get('0');
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            localizationsDelegates: AppLocalizations.localizationsDelegates,
            supportedLocales: AppAssets.getLocals(appProfile!),
            onGenerateTitle: (context) {
              var t = AppLocalizations.of(context);
              return t!.appTitle;
            },
            themeMode: AppAssets.themeModeGeter(appProfile),
            theme: ThemeData.light(),
            darkTheme: ThemeData.dark(),
            initialRoute: '/',
            routes: {
              '/': (context) {
                return  const HomePage();
              }
            },
          );
        });
  }
}

homepage.dart

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

  @override
  Widget build(BuildContext context) {
    print('homepage rebuils');
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.appTitle),
      ),
      body: Center(
        child: Consumer(builder: (context, WidgetRef ref, __) {
          return Column(
            children: [
              TextButton(
                  onPressed: () {
                    ref.read(hiveDataStoreProvider).updateBox(
                          locale: 'ar', themeMode: ThemeModeCustomized.dark
                        );
                  },
                  child: const Text('العربية')),
              TextButton(
                  onPressed: () {
                    ref.read(hiveDataStoreProvider).updateBox(
                          locale: 'en', themeMode: ThemeModeCustomized.light
                        );
                  },
                  child: const Text('English')),
            ],
          );
        }),
      ),
    );
  }
}

我认为MyApp类中的一些东西需要更改,我使用ValueListenableBuilder是因为我在Hive官方包页面中看到了它。为什么应用需要重新启动才能在区域设置中生效?不像应用主题,它工作得很完美。
这里是我的app_assets.dart代码(只是额外的信息):

class AppAssets {
 

  static List<Locale> getLocals(AppProfile appProfile) {
    switch (appProfile.locale) {
      case 'ar':
        return [const Locale('ar', '')];

      case 'en':
        return [const Locale('en', '')];
      case '':
        return AppLocalizations.supportedLocales;
      default:
        return AppLocalizations.supportedLocales;
    }
  }

  static ThemeMode themeModeGeter(AppProfile? appProfile) {
    switch (appProfile?.themeMode.name) {
      case 'dark':
        {
          return ThemeMode.dark;
        }

      case 'light':
        {
          return ThemeMode.light;
        }

      case 'system':
        {
          return ThemeMode.system;
        }
      default:
        ThemeMode.system;
    }
    return ThemeMode.system;
  }

 
}
wpcxdonn

wpcxdonn1#

我的错误是我更新了supportedLocales而没有更新MaterialApp小部件中的locale,我会保留这个问题,虽然它可能对其他人有提示。

supportedLocales: AppAssets.getLocals(appProfile),
 locale: Locale('$appProfile.locale',''),

相关问题