微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我尝试在 Flutter 中使用提升状态,但我收到“参数不匹配的关闭调用” 第一种方法从路线返回一个物体第二种方法在保留子控件的同时更改父控件

如何解决我尝试在 Flutter 中使用提升状态,但我收到“参数不匹配的关闭调用” 第一种方法从路线返回一个物体第二种方法在保留子控件的同时更改父控件

我将数据从父级传递给子级,其中一个参数是 Fn。我需要的是再次将数据从孩子返回给父母,但我收到如下错误

[ 参数不匹配的闭包调用函数 '_ReservationBranchesSlotsScreenState._changeData' 接收器:闭包: ({String areaId,int CoastPerPerson,int selectedBranchChecked,String 格式化,bool showCreateReservationButton,bool isExpanded,int expandindex}) => 来自函数“_changeData@176179245”的无效:。试过 调用:_ReservationBranchesSlotsScreenState._changeData(areaId: "d98a4e0e-d408-40c8-b387-9a405683a389",CoastPerPerson: 0,Expandedindex: -1,格式化: null,isExpanded: false,selectedBrnachChecked: 0,showCreateReservationButton: false) 找到: _ReservationBranchesSlotsScreenState._changeData({String areaId,String formatted,bool showCreateReservationButton,int Expandedindex}) => 无效]

我在父控件中创建了一个函数来执行一些操作,并将这个 Fn 传递给子控件,如下所示。

这是父小部件 Fn:

void _changeData({
  String areaId,int coastPerPerson,int expandedindex
  }){
    setState(() {
          _areaId = areaId;
          _coastPerPerson = coastPerPerson;
          _selectedBranchChecked = selectedBranchChecked;
          _formatted = formatted; 
          _showCreateReservationButton = showCreateReservationButton;
          _isExpanded = isExpanded;
          _expandedindex = expandedindex;
        });
  }

当我将这个 Fn 传递给子部件时也在下面:

SelectBranchWidget(
    branches: _branches,coastPerPerson: _coastPerPerson,areaId: _areaId,selectedBranchChecked: _selectedBranchChecked,formatted: _formatted,isExpanded: _isExpanded,showCreateReservationButton: _showCreateReservationButton,expandedindex: _expandedindex,***changeData: _changeData,***
  ),

这是我需要再次将数据从它返回给父级的子小部件:

class SelectBranchWidget extends StatefulWidget {
  List<RestaurantBranch> branches;
  int coastPerPerson;
  String areaId;
  int selectedBranchChecked;
  String formatted;
  bool isExpanded;
  bool showCreateReservationButton;
  int expandedindex;
  Function changeData;
  SelectBranchWidget(
      {this.branches,this.coastPerPerson,this.areaId,this.selectedBranchChecked,this.formatted,this.isExpanded,this.showCreateReservationButton,this.expandedindex,this.changeData,});
  @override
  _SelectBranchWidgetState createState() => _SelectBranchWidgetState();
}

class _SelectBranchWidgetState extends State<SelectBranchWidget> {
  void _changedValues(int i,int branchAreaIndex) {
    widget.coastPerPerson = widget.branches[i].branchAreas[branchAreaIndex].costPerSeat;
    widget.areaId = widget.branches[i].branchAreas[branchAreaIndex].guid;
    print('areaId IS ${widget.areaId}');
      widget.selectedBranchChecked = i;
      widget.formatted = null;
      widget.isExpanded = false;
      widget.showCreateReservationButton = false;
      widget.expandedindex = -1;
    widget.changeData(
      areaId: widget.areaId,coastPerPerson: widget.coastPerPerson,selectedBrnachChecked:widget.selectedBranchChecked,formatted: widget.formatted,showCreateReservationButton:widget.showCreateReservationButton,isExpanded:widget.isExpanded,expandedindex: widget.expandedindex
      );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: Boxdecoration(
          color: Theme.of(context).primaryColorDark,borderRadius: BorderRadius.all(Radius.circular(10))),padding: EdgeInsets.all(8),margin: EdgeInsets.only(left: 16,right: 16),child: Column(
        mainAxisSize: MainAxisSize.min,children: [
          Align(
            alignment: Alignment.centerLeft,child: Text(
              'Select Branch',style: TextStyle(
                  color: Colors.white,fontSize: 20,fontWeight: FontWeight.bold),),SizedBox(
            height: 8,Align(
            alignment: Alignment.centerLeft,child: Padding(
              padding: const EdgeInsets.only(left: 8.0),child: Text(
                'Number of branches = ${widget.branches.length}',style: TextStyle(color: Colors.grey,fontSize: 10),SizedBox(
            height: 16,ConstrainedBox(
            constraints:
                BoxConstraints(maxHeight: 230,maxWidth: double.infinity),child: ListView.builder(
              shrinkWrap: true,itemCount: widget.branches.length,itemBuilder: (ctx,i) {
                return GestureDetector(
                  onTap: () {
                    if (widget.branches[i].branchAreas.length == 1) {
                      _changedValues(i,0);
                      return;
                    }
                    showDialog(
                        context: context,builder: (BuildContext context) {
                          return AlertDialog(
                            backgroundColor: Theme.of(context).backgroundColor,title: Text(
                              'Select Area',style: TextStyle(
                                  color: Colors.white,content: Container(
                              decoration: Boxdecoration(
                                color: Theme.of(context).primaryColorDark,borderRadius: BorderRadius.all(
                                  Radius.circular(10),// height: (_branches[i].branchAreas.length == 1)
                              //     ?70
                              //     : (_branches[i].branchAreas.length == 2)
                              //     ? 100
                              //     :150,width: 100.0,child: ConstrainedBox(
                                constraints: BoxConstraints(maxHeight: 120),child: ListView.builder(
                                  shrinkWrap: true,itemCount:
                                      widget.branches[i].branchAreas.length,itemBuilder:
                                      (BuildContext context,int index) {
                                    return GestureDetector(
                                      onTap: () {
                                       _changedValues(i,index);
                                        Navigator.of(context).pop();
                                      },child: Padding(
                                        padding: const EdgeInsets.only(
                                            top: 16,left: 36.0,right: 36),child: Column(
                                          crossAxisAlignment:
                                              CrossAxisAlignment.start,children: [
                                            Text(
                                              widget.branches[i]
                                                  .branchAreas[index].name,style: TextStyle(
                                                  color: Colors.white),Divider(
                                              color: Colors.grey,thickness: 1,],);
                                  },);
                        });
                  },child: Card(
                    elevation: 8,shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12),color: Theme.of(context).backgroundColor,child: Container(
                      padding: EdgeInsets.all(20),child: Row(
                        mainAxisSize: MainAxisSize.min,mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
                          Text(
                            widget.branches[i].branchdistrict.name,style: TextStyle(color: Colors.white,fontSize: 16),(widget.selectedBranchChecked == i)
                              ? Container(
                                  height: 40,width: 40,child: Image.asset(
                                    getAssetsName(AssetsImage.checkIcon),fit: BoxFit.cover,)
                              : Container(
                                  padding: EdgeInsets.only(top: 5,bottom: 5),height: 40,decoration: Boxdecoration(
                                    shape: BoxShape.circle,color: Colors.white,child: SizedBox(),);
              },);
  }
}

解决方法

您可以使用两种方法来实现这一点。

如果您想从路线返回(从下一个屏幕到上一个),请使用第一个

如果您想在同一屏幕上从其子窗口小部件更改父窗口小部件,请使用第二种方法。

第一种方法(从路线返回一个物体)

为您传递的数据创建一个模型。

class MyModel {
  int coastPerPerson;
  String areaId;
  int selectedBranchChecked;
  String formatted;
  bool isExpanded;
  bool showCreateReservationButton;
  int expandedIndex;
  Function changeData;

  MyModel({
    this.areaId,this.coastPerPerson,this.selectedBranchChecked,this.formatted,this.isExpanded,this.showCreateReservationButton,this.expandedIndex,});

}

我假设你的父母看起来像这样。你从父页面导航到 选择BranchWidget页面

class YourParentWidget extends StatefulWidget {
  YourParentWidget({Key key}) : super(key: key);

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

class _YourParentWidgetState extends State<YourParentWidget> {


  navigateAndChangeData(){
    Navigator.of(context).push(MaterialPageRoute(builder: (context) {
      return SelectBranchWidget();
    })).then((value) {
      ///Use this to get value from next screen to PArent Screen
      if(value != null) {
        var model = value as MyModel;
        //Now you have access to all returning values
        //model.areaId
        //model.coastPerPerson
        //model.selectedBranchChecked
        //...
        ///Make changes accordingly
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ///Your UI Conponents....
    );
  }
}

现在在 SelectBranchWidget Widget 中,您需要在 _changedValues 函数中做的是返回模型值。即


class SelectBranchWidget extends StatefulWidget {
  List<RestaurantBranch> branches;
  int coastPerPerson;
  String areaId;
  int selectedBranchChecked;
  String formatted;
  bool isExpanded;
  bool showCreateReservationButton;
  int expandedIndex;
  Function changeData;
  SelectBranchWidget(
      {this.branches,this.areaId,this.changeData,});
  @override
  _SelectBranchWidgetState createState() => _SelectBranchWidgetState();
}

class _SelectBranchWidgetState extends State<SelectBranchWidget> {
  void _changedValues(int i,int branchAreaIndex) {
    MyModel model = MyModel(
        areaId: widget.branches[i].branchAreas[branchAreaIndex].guid,coastPerPerson: widget.branches[i].branchAreas[branchAreaIndex].costPerSeat,selectedBranchChecked: 1,formatted: null,isExpanded: false,showCreateReservationButton: false,expandedIndex: -1
    );

    Navigator.of(context).pop(model);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          color: Theme.of(context).primaryColorDark,borderRadius: BorderRadius.all(Radius.circular(10))),padding: EdgeInsets.all(8),margin: EdgeInsets.only(left: 16,right: 16),child: Column(
        mainAxisSize: MainAxisSize.min,children: [
          Align(
            alignment: Alignment.centerLeft,child: Text(
              'Select Branch',style: TextStyle(
                  color: Colors.white,fontSize: 20,fontWeight: FontWeight.bold),),SizedBox(
            height: 8,Align(
            alignment: Alignment.centerLeft,child: Padding(
              padding: const EdgeInsets.only(left: 8.0),child: Text(
                'Number of branches = ${widget.branches.length}',style: TextStyle(color: Colors.grey,fontSize: 10),SizedBox(
            height: 16,ConstrainedBox(
            constraints:
            BoxConstraints(maxHeight: 230,maxWidth: double.infinity),child: ListView.builder(
              shrinkWrap: true,itemCount: widget.branches.length,itemBuilder: (ctx,i) {
                return GestureDetector(
                  onTap: () {
                    if (widget.branches[i].branchAreas.length == 1) {
                      _changedValues(i,0);
                      return;
                    }
                    showDialog(
                        context: context,builder: (BuildContext context) {
                          return AlertDialog(
                            backgroundColor: Theme.of(context).backgroundColor,title: Text(
                              'Select Area',style: TextStyle(
                                  color: Colors.white,content: Container(
                              decoration: BoxDecoration(
                                color: Theme.of(context).primaryColorDark,borderRadius: BorderRadius.all(
                                  Radius.circular(10),// height: (_branches[i].branchAreas.length == 1)
                              //     ?70
                              //     : (_branches[i].branchAreas.length == 2)
                              //     ? 100
                              //     :150,width: 100.0,child: ConstrainedBox(
                                constraints: BoxConstraints(maxHeight: 120),child: ListView.builder(
                                  shrinkWrap: true,itemCount:
                                  widget.branches[i].branchAreas.length,itemBuilder:
                                      (BuildContext context,int index) {
                                    return GestureDetector(
                                      onTap: () {
                                        _changedValues(i,index);
                                        Navigator.of(context).pop();
                                      },child: Padding(
                                        padding: const EdgeInsets.only(
                                            top: 16,left: 36.0,right: 36),child: Column(
                                          crossAxisAlignment:
                                          CrossAxisAlignment.start,children: [
                                            Text(
                                              widget.branches[i]
                                                  .branchAreas[index].name,style: TextStyle(
                                                  color: Colors.white),Divider(
                                              color: Colors.grey,thickness: 1,],);
                                  },);
                        });
                  },child: Card(
                    elevation: 8,shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12),color: Theme.of(context).backgroundColor,child: Container(
                      padding: EdgeInsets.all(20),child: Row(
                        mainAxisSize: MainAxisSize.min,mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
                          Text(
                            widget.branches[i].branchDistrict.name,style: TextStyle(color: Colors.white,fontSize: 16),(widget.selectedBranchChecked == i)
                              ? Container(
                            height: 40,width: 40,child: Image.asset(
                              getAssetsName(AssetsImage.checkIcon),fit: BoxFit.cover,)
                              : Container(
                            padding: EdgeInsets.only(top: 5,bottom: 5),height: 40,decoration: BoxDecoration(
                              shape: BoxShape.circle,color: Colors.white,child: SizedBox(),);
              },);
  }
}

第二种方法(在保留子控件的同时更改父控件)

使您的父小部件的状态类和 changeData 函数公开(即删除状态类名称前的下划线) 即


class YourParentWidget extends StatefulWidget {
  YourParentWidget({Key key}) : super(key: key);

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

class YourParentWidgetState extends State<YourParentWidget> {

  String _areaId;
  int _coastPerPerson;
  int _selectedBranchChecked;
  String _formatted;
  bool _showCreateReservationButton;
  bool _isExpanded;
  int _expandedIndex;

  void changeData({
    String areaId,int coastPerPerson,int selectedBranchChecked,String formatted,bool showCreateReservationButton,bool isExpanded,int expandedIndex
  }){
    setState(() {
      _areaId = areaId;
      _coastPerPerson = coastPerPerson;
      _selectedBranchChecked = selectedBranchChecked;
      _formatted = formatted;
      _showCreateReservationButton = showCreateReservationButton;
      _isExpanded = isExpanded;
      _expandedIndex = expandedIndex;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      ///Your UI Conponents....
    );
  }
}

然后将 widget.key 从 YourParentWidget 传递给您的 SelectBranchWidget(如果您在 YourParentWidget 的 UI 中使用它),即

return Scaffold(
      body: Column(
       children: [
         ///Your UI Conponents....
         SelectBranchWidget(parentKey: widget.key,///... Other PArameters as well
         )
       ],)

    );

现在在您的 SelectBranchWidget 小部件中,执行以下操作



class SelectBranchWidget extends StatefulWidget {
  GlobalKey<YourParentWidgetState> parentKey;
  List<RestaurantBranch> branches;
  int coastPerPerson;
  String areaId;
  int selectedBranchChecked;
  String formatted;
  bool isExpanded;
  bool showCreateReservationButton;
  int expandedIndex;
  Function changeData;
  SelectBranchWidget(
      {
        this.parentKey,this.branches,int branchAreaIndex) {
    widget.coastPerPerson = widget.branches[i].branchAreas[branchAreaIndex].costPerSeat;
    widget.areaId = widget.branches[i].branchAreas[branchAreaIndex].guid;
    print('areaId IS ${widget.areaId}');
    widget.selectedBranchChecked = i;
    widget.formatted = null;
    widget.isExpanded = false;
    widget.showCreateReservationButton = false;
    widget.expandedIndex = -1;
    ///Then do this to make changes to your parent widget's state
    widget.parentKey.currentState.changeData(
        areaId: widget.areaId,coastPerPerson: widget.coastPerPerson,selectedBrnachChecked:widget.selectedBranchChecked,formatted: widget.formatted,showCreateReservationButton:widget.showCreateReservationButton,isExpanded:widget.isExpanded,expandedIndex: widget.expandedIndex
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          color: Theme.of(context).primaryColorDark,);
  }
}

编辑:您只需要像 YourParentWidget

一样调用(无论您从何处启动它)您的 YourParentWidget(key: GlobalKey<YourParentWidgetState>())

如有错别字请见谅

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。