如何在ListView的顶部插入小部件?

时间:2018-03-01 23:35:13

标签: dart flutter

简要说明:

在我的所有代码示例中,您都会看到material.Widget而非Widget之类的内容。这是因为我喜欢这样命名我的导入,例如:

import 'package:flutter/material.dart' as material;

我的问题:

我正在尝试使ListView在列表顶部显示新添加的小部件。我有一个简单的有状态窗口小部件,它只包含一个模型列表(包含构建进入ListView的窗口小部件的必要信息的类),并且应该根据该列表构建ListView的子窗口。

class Page extends material.StatefulWidget {
  final List<CardModel> cardModels;
  Page(this.cardModels);

  @override
  _PageState createState() => new _PageState(cardModels);
}

class _PageState extends material.State<Page> {
  List<CardModel> cardModels;

  _PageState(this.cardModels);

  @override
  material.Widget build(material.BuildContext context) {
    return new material.ListView(
      children: cardModels.map((cardModel) => new Card(cardModel.cardID)).toList(),
    );
  }
}

我期望的行为是,每当调用构建方法(并正确使用setState)时,ListView应该正确重建并按列表的顺序包含子窗口小部件。如果我只是按顺序将新模型添加到cardModels中,它就会成功执行此操作:

cardModels.add(new CardModel(nextID++));

您可以看到小部件按顺序添加,其ID正确递增:

enter image description here

但是,我希望在顶部插入较新的小部件(在顶部会显示较高的ID)。为了实现这一点,我尝试在列表的开头插入新模型:

cardModels.insert(0, new CardModel(nextID++));

不幸的是,我没有看到正确的小部件,而是一次又一次地获取id为0的小部件:

enter image description here

我知道模型列表正在正确更新,因为我可以打印出来并按降序查看ID。我假设有一些关于flutter如何检测导致此行为的小部件的更改,但经过大量阅读后,我仍然无法弄明白。任何帮助将非常感激。另外,我在小部件中调用set state,最终构建页面(包含ListView的小部件)作为其子代之一:

btn = new FloatingActionButton(
          onPressed: () => setState(_pageController.addCard),
          tooltip: 'Upload File',
          child: new Icon(Icons.file_upload),
        );

_pageController是修改模型列表的对象。如果这还不够,请告诉我,我很乐意提供更多代码或回答任何问题。

3 个答案:

答案 0 :(得分:3)

有一个简单的快速修复方法,使用"ghw"覆盖, 通过检查didWidgetUpdate中的cardModels对象在作为参数传递的cardModels中是否相同。 像这样

oldWidget

下面的完整示例

 @override
  void didUpdateWidget(covariant Page oldWidget) {
    if (widget.cardModels != oldWidget.cardModels) {
      setState((){
        cardModels = widget.cardModels;
      });
    }
    super.didUpdateWidget(oldWidget);
  }

答案 1 :(得分:1)

事实证明,我制作的Card小部件不需要是有状态的。我将它改为无国籍,它解决了问题。不知道为什么将它们作为有状态会破坏它。

答案 2 :(得分:0)

FloatingActionButton上更改函数以插入新项目,然后调用setState,如:

 cardModels.insert(0, new CardModel(nextId++)) ;
 setState(() {
     cardModels = cardModels;
 });

希望有所帮助!