首页 > 解决方案 > 在 Flutter 中动态创建一列行的好方法是什么

问题描述

所以理想情况下,我想让用户在按下按钮时从我的列中动态添加或删除一行。就像按下 + 按钮时一样,当按下 X 时,会在列中添加一行,反之亦然。但是,当我尝试使用相应的 X 按钮删除一行时,问题就来了。似乎我的方法只能在 x 被击中时删除随机行,而不是预期的行。如果用户已经在某行中放入数据然后只想删除该行,那么这种行为可能对用户来说已经足够好了。

r0..... +

r1..... X(当 X 在这里被击中时,r2 或其他一些行可能会被删除,其他 X 按钮也是如此)

r2..... X

到目前为止,我采用了两种方法来实现我想要的功能。第一个是使用简单的 valuenotifier 和 for 循环。如

final number = new ValueNotifier(0);

new IconButton(
  icon: Icon(Icons.add),
  onPressed: () {
    number.value++;
    print(number.value);
    setState(() {});
  })

new Column(
  children: buildPartsWidget(number.value),
)

List<Widget> buildPartsWidget(int counts){
    List<Widget> ret = [];
    for(int i = 0; i < counts; i++){
      var temp = buildPartsRow();
      ret = List.from(ret)..add(temp);
    }
    return ret;
  }

Row buildPartsRow(int key) {
    return new Row(children: <Widget>[

      new IconButton(
        icon: Icon(Icons.clear), 
        onPressed: () {
          number.value--;
          setState(() {});
        })
    ]);
  }

第二种是使用 map 将一行与一个数字配对,这两个都不起作用,例如:

Map<int, Row> rowMap = new Map();
int rowIndex;

List<Widget> rowList(){
    List<Widget> ret = [];
    rowMap.forEach((k, v) => ret.add(v));
    return ret;
  } 

new IconButton(
  icon: Icon(Icons.add),
  onPressed: () {
    rowMap[rowIndex] = buildPartsRow(rowIndex);
    rowIndex++;
    setState(() {});
  })

new Column(
  children: rowList
)


Row buildPartsRow(int key) {
    return new Row(children: <Widget>[

      new IconButton(
        icon: Icon(Icons.clear), 
        onPressed: () {
          rowMap.remove(key);
          setState(() {});
        })
    ]);
  }

我觉得我理解这两种方法的根本问题。据我了解,之所以会出现这种行为,是因为在这两种方法中,颤振都会重建条目列,并且没有办法也不会“关心”行中的输入数据。我应该如何解决我的方法?还是有更好的方法来实现我的预期功能?

我也尝试过使用 listView 但它对我不起作用。由于我正在使用的所有这些小部件都已经在列表视图中,因此在列表视图中使用列表视图似乎需要我通过使用容器或尺寸框来限制内部列表视图的大小,这将在我的表单上给我一个框。我不想要表格上的方框。有没有办法使用列表视图但不需要一个框来限制它的大小?

标签: user-interfaceflutterwidgetsetstate

解决方案


小部件动态列的好方法是使用 aListView.builder代替。在这里找到文档:https ://api.flutter.dev/flutter/widgets/ListView/ListView.builder.html

ListView.builder(
  itemCount: rowMap.length,
  itemBuilder: (context, index) {
    return buildPartsRow(rowMap[index]);
  }
)

推荐阅读