无需父子关系即可从其他不相关的小部件更改小部件状态的简便方法

时间:2020-04-03 12:16:50

标签: flutter

我无法找到一种简单的方法来从另一个不相关的小部件(没有父子关系)更改小部件的状态。我已经成功地从另一个窗口小部件调用了一个函数,但是该函数无法在窗口小部件内使用setState。我想从另一个小部件更改此小部件的状态。

如果可能的话,我想避免使用复杂的状态管理,例如bloc模式,redux,mobx等。仅用扑扑的简单方法就可以了。

class MyBottomNavigator extends StatefulWidget {
  final _MyBottomNavigatorState _myBottomNavigatorState  = _MyBottomNavigatorState();

  @override
  _MyBottomNavigatorState createState() => _myBottomNavigatorState;

  Future<void> getInitialConnection() async{
    await _myBottomNavigatorState.getInitialConnection();
  }
}

class _MyBottomNavigatorState extends State<MyBottomNavigator> {
  int _selectedIndex = 0;
  Connection selectedConnection;
  List<Widget> _children = [];

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: myAppBar(),
        drawer: MyDrawer(),
        body: myBody(),
        bottomNavigationBar: myBottomNavigation());
  }

  Future<void> getInitialConnection() async {
    List<Connection> connectionList =
        await ConnectionDBProvider.db.getAllConnections();
    if (connectionList.length > 0) {
      selectedConnection = connectionList[0];
      setState(() {
        _children = [
          ReportsPage(
            baseurl: selectedConnection.baseurl,
            username: selectedConnection.username,
            password: selectedConnection.password,
          ),
          OrdersListPage(
            baseurl: selectedConnection.baseurl,
            username: selectedConnection.username,
            password: selectedConnection.password,
          ),
          ProductsListPage(
            baseurl: selectedConnection.baseurl,
            username: selectedConnection.username,
            password: selectedConnection.password,
          ),
          CustomersListPage(
            baseurl: selectedConnection.baseurl,
            username: selectedConnection.username,
            password: selectedConnection.password,
          )
        ];
      });
    }
  }

  Widget myAppBar() {
    Widget myAppBarWidgetData;
    if (!(selectedConnection is Connection)) {
      myAppBarWidgetData = AppBar(
        title: Text("Setup"),
      );
    }
    return myAppBarWidgetData;
  }

  Widget myBody() {
    Widget myBodyWidgetData = SizedBox.shrink();
    if (selectedConnection is Connection) {
      myBodyWidgetData =
          IndexedStack(index: _selectedIndex, children: _children);
    } else {
      final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
          new GlobalKey<RefreshIndicatorState>();
      myBodyWidgetData = RefreshIndicator(
        key: _refreshIndicatorKey,
        onRefresh: getInitialConnection,
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(20),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  "Kindly add a connection to manage woocommerce",
                  textAlign: TextAlign.center,
                ),
                SizedBox(
                  height: 20,
                ),
                Container(
                  height: 45,
                  width: 200,
                  child: RaisedButton(
                    color: Theme.of(context).primaryColor,
                    textColor: Colors.white,
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => AddConnectionPage(
                            refreshConnectionsList: getInitialConnection,
                          ),
                        ),
                      );
                    },
                    child: Text(
                      "Add Connection",
                      style: Theme.of(context).textTheme.button,
                    ),
                  ),
                )
              ],
            ),
          ),
        ),
      );
    }
    return myBodyWidgetData;
  }

  Widget myBottomNavigation() {
    Widget myBottomNavigationWidgetData = SizedBox.shrink();
    if (selectedConnection is Connection) {
      myBottomNavigationWidgetData = BottomNavigationBar(
          // backgroundColor: Colors.purple, //Not Working Don't Know why
          showSelectedLabels: true,
          showUnselectedLabels: true,
          unselectedItemColor: Config.colors["lightTheme"]
              ["bottomNavInactiveColor"],
          selectedItemColor: Config.colors["lightTheme"]["mainThemeColor"],
          currentIndex: _selectedIndex,
          onTap: (int index) {
            setState(() {
              _selectedIndex = index;
            });
          },
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.insert_chart),
              title: Text('Reports'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.assignment),
              title: Text('Orders'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.collections),
              title: Text('Products'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.people),
              title: Text('Customers'),
            ),
          ]);
    }
    return myBottomNavigationWidgetData;
  }
}

下面是我要使用此功能更改上述小部件状态的小部件

 insertConnection() async {
    if (widget.id is int &&
        baseurl is String &&
        baseurl.isNotEmpty &&
        username is String &&
        username.isNotEmpty &&
        password is String &&
        password.isNotEmpty) {
      setState(() {
        isSubmitButtonLoading = true;
      });
      await ConnectionDBProvider.db.updateConnection(Connection(
          id: widget.id,
          baseurl: baseurl,
          username: username,
          password: password));
      setState(() {
        isSubmitButtonLoading = false;
      });
      scaffoldKey.currentState.showSnackBar(SnackBar(
        content: Text("Connection updated successfully..."),
        duration: Duration(seconds: 3),
      ));
      if (widget.refreshConnectionsList != null) {
        widget.refreshConnectionsList();
      }
      MyBottomNavigator myBottomNavigator = MyBottomNavigator();
      myBottomNavigator.getInitialConnection();
    }
  }

从另一个小部件调用setState时出现以下错误。

E/flutter (31813): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: setState() called in constructor: _MyBottomNavigatorState#737d1(lifecycle state: created, no widget, not mounted)
E/flutter (31813): This happens when you call setState() on a State object for a widget that hasn't been inserted into the widget tree yet. It is not necessary to call setState() in the constructor, since the state is already assumed to be dirty when it is initially created.
E/flutter (31813): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1136:9)
E/flutter (31813): #1      State.setState (package:flutter/src/widgets/framework.dart:1147:6)
E/flutter (31813): #2      _MyBottomNavigatorState.getInitialConnection (package:woocommerceadmin/main.dart:83:7)
E/flutter (31813): <asynchronous suspension>
E/flutter (31813): #3      MyBottomNavigator.getInitialConnection (package:woocommerceadmin/main.dart:54:35)
E/flutter (31813): #4      _EditConnectionPageState.insertConnection (package:woocommerceadmin/src/connections/widgets/EditConnectionPage.dart:203:25)
E/flutter (31813): #5      _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
E/flutter (31813): #6      _rootRunUnary (dart:async/zone.dart:1134:38)
E/flutter (31813): #7      _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (31813): #8      _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
E/flutter (31813): #9      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
E/flutter (31813): #10     Future._propagateToListeners (dart:async/future_impl.dart:709:32)
E/flutter (31813): #11     Future._completeWithValue (dart:async/future_impl.dart:524:5)
E/flutter (31813): #12     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
E/flutter (31813): #13     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
E/flutter (31813): #14     ConnectionDBProvider.updateConnection (package:woocommerceadmin/src/db/ConnectionDBProvider.dart)E/flutter (31813): #15     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
E/flutter (31813): #16     _rootRunUnary (dart:async/zone.dart:1134:38)
E/flutter (31813): #17     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (31813): #18     _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
E/flutter (31813): #19     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
E/flutter (31813): #20     Future._propagateToListeners (dart:async/future_impl.dart:709:32)
E/flutter (31813): #21     Future._completeWithValue (dart:async/future_impl.dart:524:5)
E/flutter (31813): #22     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
E/flutter (31813): #23     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
E/flutter (31813): #24     SqfliteDatabaseMixin.txnSynchronized (package:sqflite_common/src/database_mixin.dart)
E/flutter (31813): #25     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
E/flutter (31813): #26     _rootRunUnary (dart:async/zone.dart:1134:38)
E/flutter (31813): #27     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (31813): #28     _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
E/flutter (31813): #29     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
E/flutter (31813): #30     Future._propagateToListeners (dart:async/future_impl.dart:709:32)
E/flutter (31813): #31     Future._completeWithValue (dart:async/future_impl.dart:524:5)
E/flutter (31813): #32     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
E/flutter (31813): #33     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
E/flutter (31813): #34     BasicLock.synchronized (package:synchronized/src/basic_lock.dart)
E/flutter (31813): #35     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64)
E/flutter (31813): #36     _rootRunUnary (dart:async/zone.dart:1134:38)
E/flutter (31813): #37     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (31813): #38     _FutureListener.handleValue (dart:async/future_impl.dart:139:18)
E/flutter (31813): #39     Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45)
E/flutter (31813): #40     Future._propagateToListeners (dart:async/future_impl.dart:709:32)
E/flutter (31813): #41     Future._completeWithValue (dart:async/future_impl.dart:524:5)
E/flutter (31813): #42     _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15)
E/flutter (31813): #43     _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13)
E/flutter (31813): #44     wrapDatabaseException (package:sqflite/src/exception_impl.dart)
E/flutter (31813): #45     _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/asyn

0 个答案:

没有答案