颤抖的全球小吃店/对话工具类

时间:2019-03-10 00:04:51

标签: flutter

我想创建一个GlobalMessageUtils类,该类将打开一个材质小吃栏或对话框而无需传递构建上下文。这样的想法是,每当发生任何错误(没有网络,错误的请求等)时,我都可以弹出小吃栏并将消息转发给用户。是否有全局context的概念?

我一直在想让我的GlobalMessageUtils类成为一个单例,该单例需要一个构建context并在MaterialApp级别对其进行实例化,但是我还没有想到工作。任何机构有什么想法?这甚至是扑打的好模式吗?如果没有,你们如何在全球范围内处理错误处理?

4 个答案:

答案 0 :(得分:0)

使用BLOC模式和Rxdart,我创建了一个UiErrorUtils

class UiErrorUtils {
 // opens snackbar
  void openSnackBar(BuildContext context, String message) async {
    await Scaffold.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
      ),
    );
  }
  // subscribes to stream that triggers open snackbar
  void subscribeToSnackBarStream(BuildContext context, PublishSubject<String> stream){
    stream.listen((String message){
      openSnackBar(context, message);
    });
  }
}

在您的StatefulWidget中,您可以使用initState钩中提供的上下文:

class WidgetThatUsesUIErrorUtils extends StatefulWidget {
  final UiErrorUtils uiErrorUtils;
  final  Bloc bloc;

  WidgetThatUsesUIErrorUtils({this.uiErrorUtils, this.bloc});

  WidgetThatUsesUIErrorUtils createState() => WidgetThatUsesUIErrorUtilsState(
        uiErrorUtils: uiErrorUtils,
        bloc: bloc,
      );
}

class WidgetThatUsesUIErrorUtilsState extends State<WidgetThatUsesUIErrorUtils> {
  final Bloc _bloc;
  final UiErrorUtils _uiErrorUtils;

  WidgetThatUsesUIErrorUtilsState({Bloc bloc, UiErrorUtils uiErrorUtils})
      : _bloc = bloc ?? Bloc(),
        _uiErrorUtils = uiErrorUtils ?? UiErrorUtils();

  @override
  void initState() {
    super.initState();
    // Subscribe to UI feedback streams from  provided _bloc
    _uiErrorUtils.subscribeToSnackBarStream(context, _bloc.snackBarSubject);

  }

}

BLOC

class Bloc extends BlocBase {
  // UI Feedback Subjects
  final PublishSubject<String> snackBarSubject = PublishSubject<String>();

  //  some function that gets data from network
  Future<bool> getDataRequest() async {
     try {
      // get request code here
      } catch(error) {
      this.snackBarSubject.add(error);
    }

  }

  @override
  void dispose() {
    snackBarSubject?.close();
  }
}

现在,您的窗口小部件已订阅了该集团的SnackBarStream。 因此,在您的集团中,每当请求失败时,您都可以将消息添加到SnackBarStream中,并且由于您的窗口小部件已通过UiErrorUtils进行了订阅,所以SnackBar会随消息触发。

答案 1 :(得分:0)

我写了一个支持应用程序范围内消息显示的包。

EZ Flutter支持仅使用一行代码就可以从应用程序内的任何位置向用户显示消息。全局消息是通过BLOC处理的,并且将小部件添加为脚手架的主体。

Github:https://github.com/Ephenodrom/EZ-Flutter

dependencies:
  ez_flutter: ^0.2.0

添加消息包装器

EzGlobalMessageWrapper作为主体添加到支架中。

Scaffold{
  appBar: ...
  body: EzGlobalMessageWrapper(
    MyWidget(
      ...
    )
  )
}

向集团添加消息

使用 get 方法通过EzMessageBloc加载EzBlocProvider

向集团添加EzMessage。受支持的EzMessageTypes是:

  • 成功(默认颜色:Colors.green)
  • INFO(默认颜色:Colors.blue)
  • 警告(默认颜色:Colors.orange)
  • 错误(默认颜色:Colors.red)
    EzBlocProvider.of<EzGlobalBloc>(context)
        .get<EzMessageBloc>(EzMessageBloc)
        .addition
        .add(EzMessage("This is a success message", EzMessageType.SUCCESS));

https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/GLOBAL_MESSAGE.md

答案 2 :(得分:0)

对于提供程序解决方案,如果您使用 BaseWidget,那么您只需创建一个基类方法并在您使用提供程序的任何地方使用它。

    class BaseWidget<T extends ChangeNotifier> extends StatefulWidget {
  final Widget Function(BuildContext context, T model, Widget child) builder;
.
.
.

showToast(BuildContext context, String message, {int durationSeconds = 5}) {
  final ScaffoldMessengerState scaffoldMessenger =
      ScaffoldMessenger.of(context);
  scaffoldMessenger.showSnackBar(SnackBar(
      content: Text(message),
      duration: Duration(seconds: durationSeconds),
      action: SnackBarAction(
        label: 'HIDE',
        onPressed: () {
          scaffoldMessenger.hideCurrentSnackBar();
        },
      )));
}

然后从您的视图中调用它。

.
.
.
showToast(context, "Factor Model Created Successfully",
          durationSeconds: 30);
          Navigator.pop(context, 'save');

答案 3 :(得分:0)

  1. 定义全局变量,例如里面main.dart
final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
  1. MaterialApp 小部件具有 scaffoldMessengerKey 属性,因此将此键设置为属性
return MaterialApp(
  debugShowCheckedModeBanner: false,
  scaffoldMessengerKey: rootScaffoldMessengerKey,
  home: Scaffold(),
);
  1. 现在您可以在应用中的任何位置显示SnackBar
rootScaffoldMessengerKey.currentState?.showSnackBar(SnackBar(content: Text('some text')));