Как использовать SharedPreferences в Bloc Pattern? - PullRequest
2 голосов
/ 07 марта 2019

Я пытаюсь использовать общие настройки в своем приложении с шаблоном блока. Ниже мой код

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

Всякий раз, когда я закрываю свое приложение и снова открываю его и нажимаю кнопку «Получить данные» в начале, даже до вставки данных, я получаю значения по умолчанию. Я знаю, что не назначаю ключи во время установки значения, что приводит к путанице в том, как использовать общие настройки с блоком. Другая проблема заключается в том, что всякий раз, когда я устанавливаю данные, код внутри кнопки «Получить данные» вызывается даже до нажатия кнопки «Получить данные», которую я не понимаю.

1 Ответ

0 голосов
/ 01 апреля 2019

В вашем коде есть два места, которые должны быть исправлены. Прежде всего, в вашем классе 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, в функции сборки вы должны обернуть Scaffold в StreamBuilder,

      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,
                    ),
                  ],
                )),
              );
            },
          ));
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...