Flutter:从 Hive 盒创建对象流

Fli*_*lik 6 asynchronous dart flutter flutter-hive

我正在尝试访问一些在整个应用程序中更改和访问的用户设置。为此,我使用 Hive 从框中检索用户设置。我想通过将检索到的对象转换为UserSettingsHive.box('settings').get(userID)被输入到StreamProvider.

我将如何变成Hive.box('settings').get(userID)一个流?

编辑:这是迄今为止我的代码实现:

本地数据库.dart

static Stream<UserSettings> get userSettings {
  return Hive.box('settings').watch(key: userID)?.map((boxEvent) {
    return boxEvent.value; // ========> value is always null from boxEvent
  });
}

static void saveUserSettings(UserSettings userPref) {
  Hive.box('settings').put(userID, userPref); 
}
Run Code Online (Sandbox Code Playgroud)

主程序.dart

class Launch extends StatefulWidget {
  @override
  _LaunchState createState() => _LaunchState();
}

class _LaunchState extends State<Launch> {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        StreamProvider<User>.value(value: AuthService.user),
        StreamProvider<UserSettings>.value(value: LocalDatabase.userSettings),
      ],
      child: MaterialApp(
        title: 'MyApp',
        home: AuthWrapper(),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

设置.dart

class SettingsScreen extends StatefulWidget {
  @override
  _SettingsScreenState createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  UserSettings _settings;

  @override
  Widget build(BuildContext context) {
    _settings = Provider.of<UserSettings>(context);

    print(_settings.useLightTheme); // =====> Always returns null

    return Scaffold(
      appBar: AppBar(title: 'Settings'),
      body: Container()
    ),
  }
}
Run Code Online (Sandbox Code Playgroud)

Fel*_*sto 7

通过这个问题,我可以假设没有办法获得手表上的初始值,只需使用listenable

ValueListenableBuilder(
  valueListenable: Hive.box('settings').listenable(),
  builder: (context, box, widget) {
    return Center(
      child: Switch(
        value: box.get('darkMode', defaultValue: false),
        onChanged: (val) => box.put('darkMode', val),
      ),
    );
  },
)
Run Code Online (Sandbox Code Playgroud)


Ser*_*kov 5

使用box.watch()

接下来是伪代码,仅作为示例

Stream<User> listen() => box
      .watch(userID)
      .map(...) // somehow map your User
      .startWith(box.get(userID)); // initial value before any changes
Run Code Online (Sandbox Code Playgroud)

PS 如果您在实施过程中遇到困难 - 请在评论中联系我寻求帮助

PS 2:该startWith方法是包提供的扩展rxdart,所以请记住这一点