我的BloC和SharedPreferences在做什么?

时间:2019-06-11 16:11:30

标签: flutter sharedpreferences

问题的继续:应用重新启动后,首选项为空。

我正在使用AppBar上的一个“设置”按钮构建一个登录屏幕,每次我重新启动该应用程序时,保存的首选项似乎都被“删除”。 我正在使用Bloc库。

我还想对代码进行改进:)。

BloC状态

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';

@immutable
abstract class WebApiConfigsState extends Equatable {
  WebApiConfigsState([List props = const []]) : super(props);
}

//Load(ing)
class WebApiConfigsLoading extends WebApiConfigsState {
  final WebApiConfigs webApiConfigs;

  WebApiConfigsLoading({this.webApiConfigs}) : super([webApiConfigs]);

  @override
  String toString() => 'WebApiConfigsLoading';
}

//Load
class WebApiConfigsLoaded extends WebApiConfigsState {
  final WebApiConfigs webApiConfigs;

  WebApiConfigsLoaded({this.webApiConfigs}) : super([webApiConfigs]);

  @override
  String toString() => 'WebApiConfigsLoaded';
}

//Save
class WebApiConfigsSaving extends WebApiConfigsState {
  final WebApiConfigs webApiConfigs;

  WebApiConfigsSaving({this.webApiConfigs}) : super([webApiConfigs]);

  @override
  String toString() => 'WebApiConfigsSaving';
}

//Save(d)
class WebApiConfigsSaved extends WebApiConfigsState {
  final WebApiConfigs webApiConfigs;

  WebApiConfigsSaved({this.webApiConfigs}) : super([webApiConfigs]);

  @override
  String toString() => 'WebApiConfigsSaving';
}

//Erro
class WebApiConfigsError extends WebApiConfigsState {
  final String error;

  WebApiConfigsError({@required this.error}) : super([error]);

  @override
  String toString() => 'WebApiConfigsError { error: $error }';
}

BloC事件

import 'package:equatable/equatable.dart';

import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';

abstract class WebApiConfigsEvent extends Equatable {}

//Load
class LoadWebApiConfigsEvent extends WebApiConfigsEvent {
  WebApiConfigs webApiConfigs;

  LoadWebApiConfigsEvent(this.webApiConfigs);

  @override
  String toString() => 'LoadWebApiConfigsEvent';
}

//Save
class SaveWebApiConfigsEvent extends WebApiConfigsEvent {
  final WebApiConfigs webApiConfigs;

  SaveWebApiConfigsEvent(this.webApiConfigs);

  @override
  String toString() => 'SaveWebApiConfigsEvent { URL: ${webApiConfigs.url} }';
}

BloC集团

import 'package:bloc/bloc.dart';

import 'package:visiogate/vg_blocs/webApiConfigs/webApiConfigs.dart';
import 'package:visiogate/vg_blocs/simple_bloc_delegate.dart';
import 'package:visiogate/vg_models/persistent_data/persistent_data.dart';
import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';

void main() {
  BlocSupervisor.delegate = SimpleBlocDelegate();
}

class WebApiConfigsBloc extends Bloc<WebApiConfigsEvent, WebApiConfigsState> {
  PersistentData _persistentData = new PersistentData();
  WebApiConfigs _wac = new WebApiConfigs("", "", "", "", "", "");

  @override
  WebApiConfigsState get initialState =>
      WebApiConfigsLoading(webApiConfigs: _wac);

  @override
  Stream<WebApiConfigsState> mapEventToState(
    WebApiConfigsEvent event,
  ) async* {
    //Load
    if (event is LoadWebApiConfigsEvent) {
      try {
        final WebApiConfigs _wac = await _persistentData.getApiConfigs();
        yield WebApiConfigsLoaded(webApiConfigs: _wac);
      } catch (error) {
        yield WebApiConfigsError(error: error.toString());
      }
    }
    //Save
    if (event is SaveWebApiConfigsEvent) {
      try {
        yield WebApiConfigsSaving(webApiConfigs: event.webApiConfigs);
        yield WebApiConfigsSaved(webApiConfigs: event.webApiConfigs);
      } catch (error) {
        yield WebApiConfigsError(error: error.toString());
      }
    }
  }
}

表格

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'package:visiogate/vg_blocs/webApiConfigs/webApiConfigs.dart';
import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';

class ConfigsForm extends StatefulWidget {
  final WebApiConfigsBloc webApiConfigsBloc;

  const ConfigsForm({Key key, @required this.webApiConfigsBloc})
      : super(key: key);

  @override
  _ConfigsFormState createState() => _ConfigsFormState();
}

class _ConfigsFormState extends State<ConfigsForm> {
  final _urlController = TextEditingController();
  final _companyController = TextEditingController();

  WebApiConfigsBloc get _webApiConfigsBloc => widget.webApiConfigsBloc;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<WebApiConfigsEvent, WebApiConfigsState>(
      bloc: _webApiConfigsBloc,
      builder: (
        BuildContext context,
        WebApiConfigsState state,
      ) {
        if (state is WebApiConfigsError) {
          _onWidgetDidBuild(() {
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('${state.error}'),
                backgroundColor: Colors.red,
              ),
            );
          });
        } else if (state is WebApiConfigsLoading) {
          _webApiConfigsBloc
              .dispatch(LoadWebApiConfigsEvent(state.webApiConfigs));
        } else if (state is WebApiConfigsLoaded) {
          _urlController.text = state.webApiConfigs.url;
          _companyController.text = state.webApiConfigs.company;
          //TODO: showSnackBar
        } else if (state is WebApiConfigsSaved) {
          _urlController.text = state.webApiConfigs.url;
          _companyController.text = state.webApiConfigs.company;
          //TODO: showSnackBar
        }

        return Column(
          children: <Widget>[
            Form(
              child: Column(
                children: [
                  TextFormField(
                    decoration: InputDecoration(labelText: 'url'),
                    controller: _urlController,
                  ),
                  TextFormField(
                    decoration: InputDecoration(labelText: 'company'),
                    controller: _companyController,
                  ),
                  RaisedButton(
                    onPressed: state is! WebApiConfigsLoading
                        ? _onSaveConfigsButtonPressed
                        : null,
                    child: Text('save'),
                  ),
                  Container(
                    child: state is WebApiConfigsLoading
                        ? CircularProgressIndicator()
                        : null,
                  ),
                ],
              ),
            ),
          ],
        );
      },
    );
  }

  void _onWidgetDidBuild(Function callback) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      callback();
    });
  }

  _onSaveConfigsButtonPressed() {
    //TODO: fazer restantes controlos
    WebApiConfigs _wac = new WebApiConfigs(
        _urlController.text,
        _companyController.text,
        "default",
        "bearer",
        "professional",
        "password");

    _webApiConfigsBloc.dispatch(SaveWebApiConfigsEvent(
      _wac,
    ));
  }
}

SharedPreferences

import 'package:shared_preferences/shared_preferences.dart';

import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';
import 'package:visiogate/vg_models/token/token.dart';

class PersistentData {
  String _apiUrl = "api_url";
  String _apiCompany = "api_company";
  String _apiInstance = "api_instance";
  String _apiAuthorization = "api_authorization";
  String _apiLine = "api_line";
  String _apiGrantType = "api_grant_type";

  Future<void> setApiConfigs(WebApiConfigs webapi) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString(_apiUrl, webapi.url);
    prefs.setString(_apiCompany, webapi.company);
    prefs.setString(_apiInstance, webapi.instance);
    prefs.setString(_apiAuthorization, webapi.authorization);
    prefs.setString(_apiLine, webapi.line);
    prefs.setString(_apiGrantType, webapi.grantType);
    return;
  }

  Future<WebApiConfigs> getApiConfigs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String _ur = prefs.getString(_apiUrl) ?? "";
    String _co = prefs.getString(_apiCompany) ?? "";
    String _ins = prefs.getString(_apiInstance) ?? "D";
    String _au = prefs.getString(_apiAuthorization) ?? "bearer";
    String _ln = prefs.getString(_apiLine) ?? "pro";
    String _gt = prefs.getString(_apiGrantType) ?? "pwd";

    WebApiConfigs webapi = new WebApiConfigs(_ur, _co, _ins, _au, _ln, _gt);
    return webapi;
  }
}

如果我不重新启动应用程序,则所有“保存的”配置都在那里!我究竟做错了什么? 这可能只是一条简单的线,但是...这让我发疯了!

先发制人。

1 个答案:

答案 0 :(得分:0)

喝完咖啡和新鲜空气之后……

问题出在表格和集团上。这是代码,这样其他人就不会发疯,这也是我对社区的贡献:

BloC集团

import 'package:bloc/bloc.dart';

import 'package:visiogate/vg_blocs/webApiConfigs/webApiConfigs.dart';
import 'package:visiogate/vg_blocs/simple_bloc_delegate.dart';
import 'package:visiogate/vg_models/persistent_data/persistent_data.dart';
import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';

void main() {
  BlocSupervisor.delegate = SimpleBlocDelegate();
}

class WebApiConfigsBloc extends Bloc<WebApiConfigsEvent, WebApiConfigsState> {
  PersistentData _persistentData = new PersistentData();
  WebApiConfigs _wac = new WebApiConfigs("", "", "", "", "", "");

  @override
  WebApiConfigsState get initialState =>
      WebApiConfigsLoading(webApiConfigs: _wac);

  @override
  Stream<WebApiConfigsState> mapEventToState(
    WebApiConfigsEvent event,
  ) async* {
    //Load
    if (event is LoadWebApiConfigsEvent) {
      try {
        event.webApiConfigs = await _persistentData.getApiConfigs();
        yield WebApiConfigsLoaded(webApiConfigs: event.webApiConfigs);
      } catch (error) {
        yield WebApiConfigsError(error: error.toString());
      }
    }
    //Save
    if (event is SaveWebApiConfigsEvent) {
      try {
        _persistentData.setApiConfigs(event.webApiConfigs);
        yield WebApiConfigsSaving(webApiConfigs: event.webApiConfigs);
        yield WebApiConfigsLoaded(webApiConfigs: event.webApiConfigs);
      } catch (error) {
        yield WebApiConfigsError(error: error.toString());
      }
    }
  }
}

表格

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'package:visiogate/vg_blocs/webApiConfigs/webApiConfigs.dart';
import 'package:visiogate/vg_models/webApiConfigs/webapi_model.dart';

class ConfigsForm extends StatefulWidget {
  final WebApiConfigsBloc webApiConfigsBloc;

  const ConfigsForm({Key key, @required this.webApiConfigsBloc})
      : super(key: key);

  @override
  _ConfigsFormState createState() => _ConfigsFormState();
}

class _ConfigsFormState extends State<ConfigsForm> {
  final _urlController = TextEditingController();
  final _companyController = TextEditingController();

  WebApiConfigsBloc get _webApiConfigsBloc => widget.webApiConfigsBloc;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<WebApiConfigsEvent, WebApiConfigsState>(
      bloc: _webApiConfigsBloc,
      builder: (
        BuildContext context,
        WebApiConfigsState state,
      ) {
        if (state is WebApiConfigsError) {
          _onWidgetDidBuild(() {
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('${state.error}'),
                backgroundColor: Colors.red,
              ),
            );
          });
        } else if (state is WebApiConfigsLoading) {
          _webApiConfigsBloc
              .dispatch(LoadWebApiConfigsEvent(state.webApiConfigs));
        } else if (state is WebApiConfigsSaving) {
          _urlController.text = state.webApiConfigs.url;
          _companyController.text = state.webApiConfigs.company;
          //TODO: showSnackBar
        } else if (state is WebApiConfigsLoaded) {
          _urlController.text = state.webApiConfigs.url;
          _companyController.text = state.webApiConfigs.company;
          //TODO: showSnackBar
        }

        return Column(
          children: <Widget>[
            Form(
              child: Column(
                children: [
                  TextFormField(
                    decoration: InputDecoration(labelText: 'url'),
                    controller: _urlController,
                  ),
                  TextFormField(
                    decoration: InputDecoration(labelText: 'company'),
                    controller: _companyController,
                  ),
                  RaisedButton(
                    onPressed: (state is! WebApiConfigsLoading)
                        ? _onSaveConfigsButtonPressed
                        : null,
                    child: Text('save'),
                  ),
                  Container(
                    child: (state is WebApiConfigsLoading)
                        ? CircularProgressIndicator()
                        : null,
                  ),
                ],
              ),
            ),
          ],
        );
      },
    );
  }

  void _onWidgetDidBuild(Function callback) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      callback();
    });
  }

  _onSaveConfigsButtonPressed() {
    WebApiConfigs _wac = new WebApiConfigs(
        _urlController.text,
        _companyController.text,
        "d",
        "bearer",
        "pro",
        "pwd");

    _webApiConfigsBloc.dispatch(SaveWebApiConfigsEvent(
      _wac,
    ));
  }
}

主要问题是我在BloC上使用“ _wac”变量而不是“ event.webApiConfigs”。还删除了状态“ WebApiConfigsSaved”,因为它的最终状态为“ WebApiConfigsLoaded”。

干杯。