重用有状态的小部件和更新状态的颤振问题

时间:2020-05-23 13:58:11

标签: flutter dart

我有这个繁忙的按钮逻辑,在api调用上,我可以通过在发生网络请求时加载指示器来替换小部件,直到完成为止。

_BusyButtonState buttonState;

class BusyButton extends StatefulWidget {
  final onTap, text;
  BusyButton({Key key, this.text, this.onTap});
  @override
  _BusyButtonState createState() {
    buttonState = _BusyButtonState();
    return buttonState;
  }
}

class _BusyButtonState extends State<BusyButton> {
  bool isBusy = false;
  void notLoading() {
    setState(() {
      isBusy = false;
    });
  }

  void loading() {
    setState(() {
      isBusy = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return isBusy
        ? CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation(Colors.blue),
            strokeWidth: 1.5,
          )
        : RaisedButton(
            color: Colors.blue,
            child:
                Text('${widget.text}', style: TextStyle(color: Colors.white)),
            onPressed: widget.onTap);
  }
}

我有一个listview构建器,我在其中使用每个项目上的此按钮来将项目的状态从活动更改为非活动,反之亦然。

BusyButton(
  key: UniqueKey(),
  text: active?"Inactive":"Active"
  onTap: () {
      sendToServer(active?true:false)
   },
)

sendToServer(bool active) async{
try {
      updateState.loading();
      var response = await CallApi().putData(
          {"active": active.toString()}, "url");
      if (response.data['success']) {
        updateState.notLoading();
        print("done");
      } else {
        updateState.notLoading();
        print("error");
      }
    } catch (e) {
      updateState.notLoading();
      print(e);
    }
}

但是,当我尝试按下按钮时,如果网络请求成功,但是加载指示符出现在列表视图中的某个随机按钮上,则它可以工作。还会在请求失败时引发以下错误。

E/flutter (25919): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: setState() called after dispose(): _OutlinedButtonState#971b3(lifecycle state: defunct, not mounted)

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

尝试使用setState。

BusyButton(
      key: UniqueKey(),
      text: active?"Inactive":"Active"
      onTap: () {
         setState(){
          sendToServer(active?true:false)
         }
       },
    )