如何根据其在flutter中的索引删除小部件

时间:2019-10-18 11:38:09

标签: flutter dart flutter-layout flutter-dependencies flutter-test

我想知道如何基于关闭按钮索引关闭适当的小部件。在此图像的此处,您可以看到输出,因此在这里,我使用位于应用程序栏中的添加按钮添加了一些小部件,现在我在容器中添加了关闭按钮,当用户按下关闭按钮时,它将删除该容器。

这是输出的图像:

enter image description here

这是我尝试过的代码

class BspUnlicensedSignupPage extends StatefulWidget {
  static const String routeName = "/bspUnlicensedSignup";
  final BspSignupCommonModel bspSignupCommonModel;

  BspUnlicensedSignupPage({
    Key key,
    @required this.bspSignupCommonModel,
  }) : super(key: key);

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

class _BspUnlicensedSignupPageState extends State<BspUnlicensedSignupPage> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  List<Object> images = List<Object>();
  Future<File> _imageFile;
  bool autovalidate = false;
  bool informationislegitimate = false;
  DateTime expirydate1 = DateTime.now();
  DateTime expirydate2 = DateTime.now();

  final format = DateFormat("yyyy-MM-dd");
  final format2 = DateFormat("yyyy-MM-dd");

  String type2 = 'Passport';
  List<String> _type = <String>[
    '',
    'Passport',
    'Driving License',
    'Voter ID card',
    'Ration Card',
    'Aadhar',
    'Other Id',
  ];
  String type = 'Passport';
  var _myWidgets = List<Widget>();
  int _index = 3;
  final Map<int, String> identification1Values = Map();
  final Map<int, String> documentValues = Map();
  final Map<int, DateTime> expiryDateValues = Map();
  final Map<int, String> issuingAuthority = Map();
  final Map<int, String> identificationPicturesValues = Map();

  final List<TextEditingController> _documentControllers = List();
  final List<TextEditingController> _issuingauthoritytype = List();
  final List<TextEditingController> _expiryDate = List();
  final List<TextEditingController> _issuingauthority = List();
  final List<List<Object>> _identificationpictures = List();

  @override
  void initState() {
    super.initState();
    setState(() {
      images.add("Add Image");
      images.add("Add Image");
      images.add("Add Image");
      images.add("Add Image");
      images.add("Add Image");
    });
  }

  void _add() {
    int keyValue = _index;
    _myWidgets = List.from(_myWidgets)
      ..add(Column(
        key: Key("$keyValue"),
        children: <Widget>[
          SizedBox(height: 10),
          Container(
            // padding: EdgeInsets.fromLTRB(18,5,18,18),
            padding: EdgeInsets.all(15),
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(10),
              boxShadow: [
                BoxShadow(
                  color: Colors.black12,
                  blurRadius: 15,
                ),
              ],
            ),
            child: Column(
              children: <Widget>[
                Stack(
                  children: <Widget>[
                    Align(
                      alignment: Alignment.topRight,
                      child: GestureDetector(
                        child: Icon(Icons.close),
                        onTap: () {
                          print("CLose pressed");
                          _myWidgets.removeAt(_index);
                        },
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Column(
                      children: <Widget>[
                        SizedBox(
                          height: 20,
                        ),
                        _buildidentificationtype1(keyValue),
                        _builddocumentnumber1(keyValue),
                        _builddate(keyValue),
                        _buildissuingauthority1(keyValue),
                        _buildidentificationpictures(keyValue),
                      ],
                    ),
                  ],
                )
              ],
            ),
          )
        ],
      ));

    setState(() => ++_index);
  }

  bool isClicked = false;

  Widget _buildidentificationtype1(int keyValue) {
    TextEditingController controller = TextEditingController();
    _issuingauthoritytype.add(controller);

    return FormBuilder(
      autovalidate: autovalidate,
      child: FormBuilderCustomField(
          attribute: "Business type",
          validators: [FormBuilderValidators.required()],
          formField: FormField(
            builder: (FormFieldState<dynamic> field) {
              return InputDecorator(
                decoration: InputDecoration(
                  prefixIcon: Icon(Icons.location_on),
                  labelText: "Business type",
                  errorText: field.errorText,
                ),
                isEmpty: type == '',
                child: new DropdownButtonHideUnderline(
                  child: new DropdownButton(
                    value: type,
                    isDense: true,
                    onChanged: (String newValue) {
                      setState(() {
                        type = controller.text = newValue;
                        field.didChange(newValue);
                      });
                    },
                    items: _type.map(
                      (String value) {
                        return new DropdownMenuItem(
                          value: value,
                          child: new Text(value),
                        );
                      },
                    ).toList(),
                  ),
                ),
              );
            },
          )),
    );
  }

  Widget _builddocumentnumber1(int keyValue) {
    TextEditingController controller = TextEditingController();
    _documentControllers.add(controller);
    return new TudoTextWidget(
      controller: controller,
      prefixIcon: Icon(FontAwesomeIcons.idCard),
      labelText: "Document Number",
      validator: Validators().validateLicenseno,
      onSaved: (val) {
        setState(() {
          documentValues[keyValue] = val;
        });
        // _licenseno = val;
      },
    );
  }

  Widget _builddate(int keyValue) {
    TextEditingController controller = TextEditingController();
    _expiryDate.add(controller);
    return DateTimeField(
      format: format,
      autocorrect: true,
      autovalidate: autovalidate,
      controller: controller,
      readOnly: true,
      decoration: InputDecoration(
          labelText: "Expiry Date",
          hintText: "Expiry Date",
          prefixIcon: Icon(
            FontAwesomeIcons.calendar,
            size: 24,
          )),
      onShowPicker: (context, currentValue) {
        return showDatePicker(
            context: context,
            firstDate: DateTime(1900),
            initialDate: currentValue ?? DateTime.now(),
            lastDate: DateTime.now());
      },
    );
  }

  Widget _buildissuingauthority1(int keyValue) {
    TextEditingController controller = TextEditingController();
    _issuingauthority.add(controller);
    return new TudoTextWidget(
      prefixIcon: Icon(FontAwesomeIcons.idCard),
      labelText: "Issuing Authority",
      validator: (val) => Validators.validateName(val, "Issuing Authority"),
      onSaved: (val) {
        setState(() {
          issuingAuthority[keyValue] = val;
        });
      },
      controller: controller,
    );
  }

  Widget _buildidentificationpictures(int keyValue) {
    return GridView.count(
      physics: NeverScrollableScrollPhysics(),
      shrinkWrap: true,
      crossAxisCount: 5,
      childAspectRatio: 1,
      children: List.generate(images.length, (index) {
        if (images[index] is ImageUploadModel) {
          ImageUploadModel uploadModel = images[index];

          return Card(
            clipBehavior: Clip.antiAlias,
            child: Stack(
              children: <Widget>[
                Image.file(
                  uploadModel.imageFile,
                  width: 300,
                  height: 300,
                ),
                Positioned(
                  right: 5,
                  top: 5,
                  child: InkWell(
                    child: Icon(
                      Icons.remove_circle,
                      size: 20,
                      color: Colors.red,
                    ),
                    onTap: () {
                      setState(() {
                        images.replaceRange(index, index + 1, ['Add Image']);
                      });
                    },
                  ),
                ),
              ],
            ),
          );
        } else {
          return Card(
            child: IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                _onAddImageClick(index);
              },
            ),
          );
        }
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    final appBar = AppBar(
      title: Text("BSP Unlicensed Details"),
      leading: IconButton(
        icon: Icon(Icons.arrow_back_ios),
        onPressed: () {
          NavigationHelper.navigatetoBack(context);
        },
      ),
      actions: <Widget>[IconButton(icon: Icon(Icons.add), onPressed: _add)],
      centerTitle: true,
    );
    final bottomNavigationBar = Container(
      color: Colors.transparent,
      height: 56,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          new FlatButton.icon(
            icon: Icon(Icons.close),
            label: Text('Clear'),
            color: Colors.redAccent,
            textColor: Colors.black,
            padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            onPressed: () {},
          ),
          new FlatButton.icon(
              icon: Icon(FontAwesomeIcons.arrowCircleRight),
              label: Text('Next'),
              color: colorStyles["primary"],
              padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
              textColor: Colors.white,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(7),
              ),
              onPressed: () async {
                setState(() {
                  autovalidate = !autovalidate;
                });
                if (_formKey.currentState.validate()) {
                  BspSignupCommonModel model = widget.bspSignupCommonModel;
                  for (var i = 0; i < _myWidgets.length; i++) {
                    String document = _documentControllers[i].text;
                    String issuingAuthorityType = _issuingauthoritytype[i].text;
                    String expiryDate = _expiryDate[i].text;
                    String issuingAuthority = _issuingauthority[i].text;
                    //  String picture = _identificationpictures[i].text;
                    print('Document: $document');
                    print('IssuingAuthorityType: $issuingAuthorityType');
                    print('ExpiryDate: $expiryDate');
                    print('IssuingAuthority: $issuingAuthority');
                    print('Picture: ${_identificationpictures.length}');
                    print(_myWidgets.length);
                    List<Licensed> listOfLicenses = new List<Licensed>();

                    Licensed licensed = new Licensed(
                        bspLicenseNumber: document,
                        bspAuthority: issuingAuthority,
                        bspExpiryDate: expiryDate,
                        bspIssuing: issuingAuthorityType);

                    licensed.bspLicenseNumber = _documentControllers[i].text;
                    licensed.bspExpiryDate = _expiryDate[i].text;
                    licensed.bspIssuing = _issuingauthoritytype[i].text;
                    licensed.bspAuthority = _issuingauthority[i].text;
                    listOfLicenses.add(licensed);
                    model.unlicensed = listOfLicenses;
                  }

                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => BspLicensedSignupTermsPage(
                              bspSignupCommonModel: model)));
                }
              }),
        ],
      ),
    );
    return new Scaffold(
      appBar: appBar,
      bottomNavigationBar: bottomNavigationBar,
      body: Container(
        height: double.infinity,
        width: double.infinity,
        child: Form(
            autovalidate: autovalidate,
            key: _formKey,
            child: Stack(
              children: <Widget>[
                Column(
                  children: <Widget>[
                    Expanded(
                      child: SizedBox(
                        child: ListView(
                          padding: const EdgeInsets.all(18.0),
                          children: _myWidgets,
                        ),
                      ),
                    ),
                  ],
                )
              ],
            )),
      ),
    );
  }
}

4 个答案:

答案 0 :(得分:1)

编辑:似乎您需要使用TypeError: func() takes exactly 2 arguments (1 given) 而不是Map,因为如果删除项目,索引可能会更改。

您可以执行以下操作:List其中int keyValue = ++_lastKey;是一个变量,每次添加项目时都会增加,它将作为唯一标识符

然后将_lastKey称为_myWidgets.removeAt(keyValue);,而不是_myWidgetsMap.remove(keyValue),如下所示:

setState()

您应该在setState(() { _myWidgetsMap.remove(keyValue); }); 内的_add()内调用代码


但是我建议您根据信息列表而不是小部件列表来构建小部件。这样,当您更改信息时,小部件将正确适应。

答案 1 :(得分:1)

class _MyHomePageState extends State<MyHomePage> {
  bool isClosed = false;

  void Closed() {
    setState(() {
      isClosed = true;
    });
    print("CLick");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: !isClosed?Center(
        child: Container(
          width: 200,
          height: 200,
          decoration: BoxDecoration(
            color: Colors.blueAccent,
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              GestureDetector(
                child: Container(
                  child: Icon(Icons.close),
                ),
                onTap: (){
                  Closed();
                },
              ),
              Text(
                'Close Here by Tap',
              ),

            ],
          ),
        ),
      ):Container(), 
    );
  }
}

此代码对我有用

答案 2 :(得分:0)

也许您可以尝试绘制或不绘制窗口小部件(如果未轻按按钮),则可以在代码中创建一个变量来处理窗口小部件的状态,并在点击关闭按钮时更改变量的值,就像这样:

bool isClosed = false;

!isClosed?MyWidget():Container()

,并且在关闭按钮的onTap()中需要包含以下内容:

setState(() {
      isClosed = true;
    });

希望对您有帮助

答案 3 :(得分:0)

我知道我迟到了,但其他人可能会觉得这很有帮助。

我遇到了完全同样的问题。我很自豪地说,经过一个小时的努力,我找到了解决方案!

简单解释一下:-

<块引用>
  1. 使用 Map 而不是 List(正如有些人已经正确建议的那样)
  2. 使用 UniqueKey().toString() 在您每次动态构建小部件时生成一个新键,并将此 对添加到 Map

这是代码片段

Map<String, MyCard> theCards = {
    '0': MyCard(
      isInitialCard: true,
    )
  };

  void removeMyCard(String cIndex) {
    setState(() {
      print(cIndex);
      substrateCards.remove(cIndex);
    });
  }

  void addMyCard() {
    setState(() {
      String id = UniqueKey().toString();
      theCards.putIfAbsent(
          id,
          () => MyCard(
                onClose: () {
                  removeMyCard(id);
                },
              ));
      print(id);
    });
  }

然后,在 ListView.builder 中,从 Map 构建,如下所示:-

ListView.builder(
                shrinkWrap: true,
                itemCount: theCards.length,
                itemBuilder: (BuildContext context, int index) {
                  String key = theCards.keys.elementAt(index);
                  return theCards[key];
                }),

不管你是从中间、结尾还是任何地方删除,它都会起作用。