在窗口小部件之间传递数据?

时间:2018-11-20 10:43:17

标签: mobile dart flutter

我有两个有状态的小部件,第一个名为MyApp,用于显示ListView构建器中的雇员列表。第二个有状态的小部件名为ActionButton,它也是一个有状态的小部件。

ActionButton小部件将返回一个“警报”对话框。在“警报”对话框中,我可以通过输入员工姓名和工资来添加新员工。

问题是,为了显示新添加的员工,我必须热重新加载应用程序。有没有一种方法可以通知MyApp小部件已经添加了新的Employee,然后在ListView构建器中显示新添加的雇员。

下面是MyApp窗口小部件的代码:

                  import 'package:flutter/material.dart';

            import './database_helper.dart';
            import './floating_action_button.dart';

            void main() async {
              DatabaseHelper databaseHelper = new DatabaseHelper();
              List employees = [];
              employees = await databaseHelper.getAllEmployees();

              runApp(MyApp(employees));
            }

            class MyApp extends StatefulWidget {
              final List employees;

              MyApp(this.employees);

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

            class _MyAppState extends State<MyApp> {
              List employees = [];

              @override
              void initState() {
                super.initState();
                employees = widget.employees;
              }

              @override
              Widget build(BuildContext context) {
                return MaterialApp(
                  home: Scaffold(
                    appBar: AppBar(
                      title: Text("Employees"),
                    ),
                    body: Container(
                      child: ListView.builder(
                        itemCount: employees.length,
                        itemBuilder: (BuildContext context, int index) {
                          return new Card(
                            child: ListTile(
                              title: Text(employees[index]["empName"]),
                              subtitle: Text(
                                employees[index]["empSalary"].toString()),
                              trailing: RaisedButton(
                                onPressed: () {
                                  removeEmployee(
                                     employees[index]["id"], index);
                                },
                                child: Icon(
                                  Icons.remove,
                                  color: Colors.white,
                                ),
                                shape: CircleBorder(),
                                color: Theme.of(context).primaryColor,
                              ),
                            ),
                          );
                        },
                      ),
                    ),
                    floatingActionButton: ActionButton(),
                  ),
                );
              }

              Future<int> removeEmployee(int id, int index) async {
                DatabaseHelper databaseHelper = new DatabaseHelper();
                var result = await databaseHelper.deleteEmployee(id);
                if (result == 1) {
                  setState(() {
                    employees.removeAt(index);
                  });
                }
                return result;
              }
            }

最后但并非最不重要的,ActionButton代码:

    import 'package:employees/database_helper.dart';
    import 'package:employees/employee.dart';
    import 'package:flutter/material.dart';

    class ActionButton extends StatefulWidget {
      @override
      _ActionButtonState createState() => _ActionButtonState();
    }

    class _ActionButtonState extends State<ActionButton> {
      var _employeeNameController = new TextEditingController();
      var _employeeSalaryController = new TextEditingController();

      @override
      Widget build(BuildContext context) {
        return FloatingActionButton(
          child: Icon(
            Icons.add,
            color: Colors.white,
          ),
          onPressed: () {
            showDialog(
              context: context,
              builder: (_) {
                return AlertDialog(
                  title: Text("Add New Employees"),
                  content: Column(
                    children: <Widget>[
                      TextField(
                        controller: _employeeNameController,
                      ),
                      TextField(
                        controller: _employeeSalaryController,
                      ),
                    ],
                  ),
                  actions: <Widget>[
                    RaisedButton(
                      onPressed: () {
                        setState(
                          () {
                            addNewEmployee();
                          },
                        );
                      },
                      child: Text("Add Employee"),
                    ),
                  ],
                );
              },
            );
          },
        );
      }

      void addNewEmployee() async {
        DatabaseHelper databaseHelper = new DatabaseHelper();
        Employee employee = new Employee(
              _employeeNameController.text,
              int.parse(_employeeSalaryController.text));
        await databaseHelper.insertEmployee(employee);
      }
    }

感谢您的帮助。 最好的问候

1 个答案:

答案 0 :(得分:1)

检查一下。 Flutter State Management

当前有三种管理状态的方法:SetState(),InheritedWidget和BLoC。

根据我的经验,如果您想要重绘一个小部件,则BLoC是最好的。这是最简单的方法。

定义BLoC和提供者:

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:rxdart/rxdart.dart';

class EmployeeProvider extends InheritedWidget {
  final employeeBloc=EmployeeBloc();
  EmployeeProvider({Key key, @required Widget child,})
      : assert(child != null),
        super(key: key, child: child);

  static EmployeeBloc of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(EmployeeProvider) as EmployeeProvider).employeeBloc;
  }

  @override
  bool updateShouldNotify(EmployeeProvider old)=>true;
}

class EmployeeBloc{
  //This is the output interface of Bloc
  ValueObservable<List<Employee>> get list => _list.stream;//seedValue: '/'
  final _list = BehaviorSubject<List<Employee>>();//seedValue: '/'

  // This is the input interface of Bloc
  Sink<List<Employee>> get listChange => _listChangeController.sink;
  final _listChangeController = StreamController<List<Employee>>();

  EmployeeBloc(){
    _listChangeController.stream.listen(_handleListChange);
  }
  // This is the logic handling input
  void _handleListChange(List<Employee> newList){
    _list.add(newList);
  }
}

用法:

  1. 将整个应用(或感兴趣的部分)包装在EmployeeProvider中
  2. 每当需要更新列表时

    EmployeeProvider.of(context).listChange.add(NewEmployeeList);
    
  3. 包装需要在StreamBuilder中重绘的小部件

    StreamBuilder<List<Employee>>( stream: EmployeeProvider.of(context).list, builder: (context, snapshot)=>ListView( children: snapshot.data.map(mapDataToListTile), ), );

只要流收到新值,StreamBuilder中的小部件就会立即重绘。

相关问题