【问题标题】:How can i remove a widget in a ListView in a specific index?如何删除特定索引中 ListView 中的小部件?
【发布时间】:2019-11-20 14:32:22
【问题描述】:

我一直在寻找几个小时,但没有成功。我有一个使用此构造函数构建的 ListView

ListView.builder( itemCount: 5, itemBuilder: (context, int index) { return ServiceCard(index: index,); }, ),

现在在 ServiceCard 小部件中,我有一个按钮可以删除 ListView 树中的当前小部件,例如第三个 ServiceCard 小部件。

尝试了很多方法都不管用。令我惊讶的是,即使是颤振文档也没有显示如何实现这样一个常见的功能。

我尝试为 ListView 提供一个变量,以便我可以访问它并删除其中所需的小部件。不幸的是,没有这样的功能。

我尝试为 ListView 提供一个准备好的 ServiceCard 小部件列表,然后我将其用于 ListView 的 itemCounter 的长度。然后从指定 ServiceCard 小部件上按钮的 setState 中的列表中删除一个项目。

我尝试使用一种方法,该方法将索引作为参数并仅在当前索引等于已删除项的索引的情况下返回 ServiceCard。不幸的是,这会删除最后一个服务卡而不是指定的服务卡。

这里是 ServiceCard 小部件:

class ServiceCard extends StatefulWidget {
  ServiceCard({this.index});

  int index;


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

class _ServiceCardState extends State<ServiceCard> {
  void onFormSubmitted() {
    var form = formKey.currentState;
    if (form.validate()) {
      form.save();
    }
  }

  @override
  Widget build(BuildContext context) {
    int index = widget.index;

    return Container(
      height: 440,
      child: Column(
        children: <Widget>[
          ExpandableRoundRectangleContainer(
            widgetList: <Widget>[
              Container(
                height: 370,
                child: Stack(
                  alignment: Alignment.bottomLeft,
                  children: <Widget>[
                    //column for tow TextField with headers
                    Column(
                      children: <Widget>[
                        HeaderTextWithFormTextFieldAndSizedBox(
                          headerText: 'Service Name',
                          hintText: 'Write your service name here...',
                          autoFocus: true,
                          iconData: Icons.info_outline,
                          validatorFunction: (String value) {
                            if (value.length > 0 && value.length < 6) {
                              return '*Service name should be more than 5 letters';
                            } else if (value.length == 0) {
                              return '* Service name is required';
                            }
                          },
                          onSaved: (String value) {},
                        ),
                        HeaderTextWithFormTextFieldAndSizedBox(
                          headerText: 'Service Description',
                          hintText: 'Write your service description here...',
                          autoFocus: false,
                          iconData: Icons.info_outline,
                          validatorFunction: (String value) {
                            if (value.length > 0 && value.length < 6) {
                              return '* Service description should be more than 5 letters';
                            } else if (value.length == 0) {
                              return '* Service description is required';
                            }
                          },
                          letterCount: 200,
                          maxLines: 3,
                          contentPadding: 13,
                          onSaved: (String value) {},
                        ),
                      ],
                    ),

                    //only add the add service button when it is the last card
                    Visibility(
//                        visible:   widget.index ==  serviceNamesList.length - 1 ,
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: RoundButtonWithIconFix(
                          text: 'Add Another Service',
                          buttonWidth: 160,
                          buttonColor: kAppLightBlueColor,
                          onButtonPressed: () {},
                          icon: Icons.add_box,
                          color: Colors.white,
                          iconTextSpacing: 5,
                          iconSize: 25,
                        ),
                      ),
                    ),

                    Positioned(
                      bottom: 50,
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: RoundButtonWithIconFix(
                          text: 'Remove Service',
                          buttonWidth: 130,
                          buttonColor: kAppLightBlueColor,
                          onButtonPressed: () {
                            setState(() {
                            });
                          },
                          icon: Icons.delete,
                          color: Colors.white,
                          iconTextSpacing: 5,
                          iconSize: 25,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
          Visibility(
//              visible: widget.index == serviceNamesList.length - 1  ,
            child: DoneButton(
              onPressed: onFormSubmitted,
            ),
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

  • build 中,您有一个index,只需使用它从该索引中删除项目
  • 嗨。请你显示一些代码,因为我尝试了很多方法,但仍然没有给出所需的方法。谢谢

标签: listview flutter delete-row


【解决方案1】:

您可以创建一个列表并将其传递给您的 ListView,然后使用 remove 函数删除实际对象并调用 setState((){}) 来刷新您的 UI。

这是您可以运行的示例:

class StreamBuilderIssue extends StatefulWidget {
  @override
  _StreamBuilderIssueState createState() => _StreamBuilderIssueState();
}

class _StreamBuilderIssueState extends State<StreamBuilderIssue> {
  List<ServiceCard> serviceCardList;

  void removeServiceCard(index) {
    setState(() {
      serviceCardList.remove(index);
    });
  }

  @override
  void initState() {
    super.initState();
    serviceCardList = List.generate(
        5, (index) => ServiceCard(removeServiceCard, index: index));
  }

  @override
  Widget build(BuildContext context) {
    print('build + ${serviceCardList.length}');
    return Scaffold(
      body: ListView(
        children: <Widget>[...serviceCardList],
      ),
    );
  }
}

class ServiceCard extends StatelessWidget {
  final int index;
  final Function(ServiceCard) removeServiceCard;

  const ServiceCard(this.removeServiceCard, {Key key, @required this.index})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text(
            'Index: ${index.toString()} Hashcode: ${this.hashCode.toString()}'),
        RaisedButton(
          color: Colors.accents.elementAt(3 * index),
          onPressed: () {
            removeServiceCard(this);
          },
          child: Text('Delete me'),
        ),
      ],
    );
  }
}

这是显示其行为的 gif external link

我正在显示索引和哈希码以表明它确实是被删除的所需对象

【讨论】:

  • “removeServiceCard(this);”怎么办?在有状态的小部件中?
猜你喜欢
  • 2020-02-15
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 2016-04-11
  • 1970-01-01
相关资源
最近更新 更多