如何在特定索引的ListView中删除小部件? [英] How can i remove a widget in a ListView in a specific index?

查看:63
本文介绍了如何在特定索引的ListView中删除小部件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在搜索小时,但没有结果.我有一个使用此构造函数构建的ListView

I have been searching for hours , to no vail. I have a ListView that is built with this constructor

ListView.builder(itemCount:5itemBuilder :(上下文,整数索引){返回ServiceCard(index:index,);},),

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

now in the ServiceCard widget I have a button to delete the current widget in the ListView tree for example the 3rd ServiceCard widget.

尝试了许多无效的方法.令我感到惊讶的是,即使是颤抖的文档也没有显示如何实现这种通用功能.

Tried many methods that didn't work. I am surprised that even the flutter documentation doesn't show how to implement such a common functionality.

我试图给ListView一个变量,以便我可以访问它并在其中删除所需的小部件.不幸的是,没有这样的功能.

I have tried giving the ListView a variable so that i can access it and remove the desired widget in it. unfortunately there is no such functionality.

我尝试为ListView准备一个准备好的ServiceCard小部件列表,然后使用它的长度作为ListView的itemCounter的长度.然后从指定ServiceCard小部件上按钮的setState中的List中移除一个项目.

I have tried giving the ListView a prepared List of ServiceCard widgets that i then used to use it's length for the itemCounter of the ListView. then removing an item form the List in the setState of the button on the specified ServiceCard widget.

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

I have tried using a method that takes an index as an argument and returns a ServiceCard only in the case where current index is equal to the index of the removed item. this unfortunately removes the last ServiceCard not the one designated.

这是ServiceCard小部件:

here is the ServiceCard widget :

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,
            ),
          ),
        ],
      ),
    );
  }
}

推荐答案

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

You could create a list and pass that to your ListView and use the remove function to remove the actual object and call setState((){}) to refresh your UI.

以下是您可以运行的示例:

Here is a sample you can run:

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 外部链接

And here is gif showing its behavior external link

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

I'm showing the index and the hashcode to show that it is indeed the desired object that gets removed

这篇关于如何在特定索引的ListView中删除小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆