如何在Bloc模式中使用SharedPreferences?

时间:2019-03-07 11:16:10

标签: dart flutter sharedpreferences

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

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中使用共享首选项的困惑。另外一个问题是,每当我设置数据时,甚至在按下我无法理解的获取数据之前,都会调用“获取数据”按钮中的代码。

1 个答案:

答案 0 :(得分:0)

您的代码上存在两个必须修复的位置。 首先,在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,
                    ),
                  ],
                )),
              );
            },
          ));
        }