基于流的flutter snapbar显示

Joe*_*ing 9 flutter rxdart

我目前有一个有趣的问题,与根据用户操作显示小吃店有关。

以上听起来很琐碎,但让我们详细说明:

我有两个屏幕:

  1. 员工名单
  2. 添加员工

应用程序使用 bloc 模式(使用流/rxdart)。

这是我想要的:

  • 用户单击员工屏幕列表中的添加员工 FAB 按钮并导航到添加员工屏幕(工作正常)
  • 用户填写员工详细信息并点击保存
  • 保存后,员工被添加到流中,并更新员工列表屏幕(工作正常)
  • 用户被导航回员工列表(工作正常)
  • 显示 Snackbar 说明已成功添加员工(这是问题所在)

我尝试了几种实现方式:

添加一个新流(employeeAdded),并在将员工添加到员工流时,另外向添加的员工推送一个布尔值。

在员工列表中,添加一个新的流构建器,并在构建器逻辑中添加小吃栏。

这会产生各种问题,例如尝试在(重新)构建页面之前显示小吃栏,等等。

问题是双重的:对于这种情况,什么是好的 UX 实践,以及对这个问题来说什么是好的解决方案?

(将根据要求发布代码)

谢谢您的帮助!

Tom*_*cki 10

有准备的食谱显示SnackbarBloc。基本上BlocListener就是为此目的而创建的。请查看https://felangel.github.io/bloc/#/recipesfluttershowsnackbar

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final dataBloc = BlocProvider.of<DataBloc>(context);
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: BlocListener(
        bloc: dataBloc,
        listener: (BuildContext context, DataState state) {
          if (state is Success) {
            Scaffold.of(context).showSnackBar(
              SnackBar(
                backgroundColor: Colors.green,
                content: Text('Success'),
              ),
            );
          }
        },
        child: YourChild()
      ),
   );
  }
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*ing 1

虽然这不是我最喜欢的答案,但我也不确定是否有更好的选择;这是我为未来的观察者所做的临时修复:

创建一个新流(在我的例子中是employeeAdded),在添加员工时,还要在流中创建一个条目:

  final _employees = BehaviorSubject<List<Employee>>(seedValue: List<Employee>());
  final _employeeAdded = BehaviorSubject();

  // streams (out)
  Observable<List<Employee>> get employees => _employees.stream;
  Observable<dynamic> get employeesAdded => _employeeAdded.stream;

  addEmployee(Employee employee) async {
    final newList = <Employee>[]..addAll(_employees.value)..add(employee);
    await _employeeRepo.upsertEmployee(employee);
    _employees.add(newList);

    _employeeAdded.add(true);
    //FIXME: Save to db
  }
Run Code Online (Sandbox Code Playgroud)

请注意,employeeAdded 中没有 SeedValue,这是为了防止小吃栏在初始加载时显示。

在我的屏幕/页面中我有一个脚手架;它的主体调用另一个方法,该方法应该解释其余的代码:

 Widget _buildBody(EmployeeBloc bloc) {
    return StreamBuilder(
      stream: bloc.employees,
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          bloc.employeesAdded.listen(
            (_) => Scaffold.of(context).showSnackBar(
                  SnackBar(
                    content: Text('Employee added'),
                  ),
                ),
          );
          bloc.seedEmployees();
          return Center(
            child: Text("No employees"),
          );
        }
        return _buildList(bloc, snapshot.data);
      },
    );
  }
Run Code Online (Sandbox Code Playgroud)

请注意使用 hasData if 来监听块。

这目前有效,但想知道是否有一个更简洁的例子。