dart - 如何在 Bloc 模式中使用 SharedPreferences?

标签 dart flutter sharedpreferences

我正在尝试在我的应用程序中使用 block 模式的共享首选项。 以下是我的代码

class PrefsStats {
  final bool isMale;
  final String name;
  final int age;

  PrefsStats(this.isMale, this.name, this.age);
}

class PrefsBloc {

  final _changePrefernce = BehaviorSubject<PrefsStats>();
  Function(PrefsStats) get changePrefs => _changePrefernce.sink.add;
  Stream<PrefsStats> get prefrence => _changePrefernce.stream;
  SharedPreferences sPrefs;

  dispose(){
    _changePrefernce?.close();
  }

  PrefsBloc(){
    _loadSharedPreferences();
  }

  Future<void> _loadSharedPreferences() async {
    sPrefs = await SharedPreferences.getInstance();
    final namePref = sPrefs.getString("name") ?? "";
    final malePref = sPrefs.getBool("male") ?? false;
    final agePref = sPrefs.getInt("age") ?? 0;
    _changePrefernce.add(PrefsStats(malePref,namePref,agePref));
  }



}

final prefsBloc = PrefsBloc();

我只想使用一个按钮插入数据并使用另一个按钮从 SharedPreferences 获取数据

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
            child: Column(
          children: <Widget>[
            SizedBox(
              height: 20,
            ),
            RaisedButton(
              onPressed: () {
                prefsBloc.changePrefs(PrefsStats(true, "argo", 21));
              },
              child: Text("Insert Data"),
            ),
            SizedBox(
              height: 20,
            ),
            RaisedButton(
              onPressed: () {
              prefsBloc.prefrence.forEach((data){
                print(data.name);
              });
              },
              child: Text("Get Data"),
            ),
            SizedBox(
              height: 20,
            ),
          ],
        )),
      ),
    );
  }

  @override
  void dispose() {
    prefsBloc?.dispose();
    super.dispose();
  }
}

每当我关闭应用程序并再次重新打开它,甚至在插入数据之前单击开始时的“获取数据”按钮时,我都会获得默认值。我知道我在设置值时没有分配键,这导致了如何使用 bloc 的共享首选项的困惑。另一个问题是每当我设置数据时,即使在按下我无法理解的“获取数据”之前,“获取数据”按钮内的代码也会被调用。

最佳答案

您的代码中有两个地方必须修复。 首先,在您的 BloC 类中,只要添加接收器,您的流就必须监听,

.
.
.
PrefsBloc(){
_loadSharedPreferences();
_changePrefernce.stream.listen(_newFunction);

}

void _newFunction(PrefsStats stats){
   if (states != null) {
      if (sPrefs != null) {
         sPrefs.setString("name", states.name);
         sPrefs.setInt("age", states.age);
         sPrefs.setBool("male", states.isMale);
         sPrefs.commit();
      }
   }
}

第二个地方是 _MyAppState 类,在构建函数中你必须用 StreamBuilder 包装 Scaffold,

      class _MyHomePageState extends State<MyHomePage> {
        String textAge = "";
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
              home: StreamBuilder(
            stream: prefsBloc.prefrence,
            builder: (context, AsyncSnapshot<PrefsStats> snapshot) {
              return Scaffold(
                body: SafeArea(
                    child: Column(
                  children: <Widget>[
                    Text((snapshot.data != null) ? snapshot.data.name : ""),
                    SizedBox(
                      height: 20,
                    ),
                    RaisedButton(
                      onPressed: () {
                        prefsBloc.changePrefs(PrefsStats(
                          true,
                          textAge.toString(),
                          21,
                        ));
                      },
                      child: Text("Insert Data"),
                    ),
                    TextFormField(
                      initialValue: (snapshot.data != null) ? snapshot.data.name : "",
                      onFieldSubmitted: (value) {
                        textAge = value;
                      },
                    ),
                    Text(textAge),
                    SizedBox(
                      height: 20,
                    ),
                    RaisedButton(
                      onPressed: () {
                        prefsBloc.prefrence.forEach((data) {
                          print(data.name);
                          setState(() {
                            textAge = data.name;
                          });
                        });
                      },
                      child: Text("Get Data"),
                    ),
                    SizedBox(
                      height: 20,
                    ),
                  ],
                )),
              );
            },
          ));
        }

关于dart - 如何在 Bloc 模式中使用 SharedPreferences?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55042512/

相关文章:

java - 创建 AlertDialog 时代码中断。我想我有上下文错误......?

asynchronous - 如何使用dart(Flutter)中的Future和.then()转换此简单的异步,等待格式化的代码?

当小部件包装在 InteractiveViewer 中时,Flutter onPanStart 会延迟调用

dart - 什么是类似 java 中的 Gson 的 flutter dart 中可用的等效库

android - 调用api时如何处理map<dynamic> null对象

android - 如何监听写入Preferences DataStore的成功或失败结果?

java - 使用 SharedPreferences 的许多用户登录

flutter - 我想为我所有的屏幕创建一个固定的 Appbar

multithreading - 在 Dart/Flutter 中使用 GPU 而非图形

google-maps - GoogleMap 的 onCameraIdle 在 SingleChildScrollView 中停止触发