【问题标题】:ListView not rebuilding when returned to screen even after using setState()?即使在使用 setState() 后返回屏幕时 ListView 不重建?
【发布时间】:2026-02-06 22:15:01
【问题描述】:

我有一个根据文件夹中文件数量填充的列表。在应用程序启动时,它会按预期正确地构建我的列表。

但在新笔记屏幕上,用户可以选择在此文件夹中保存笔记。当我回到这个屏幕时,列表不会根据添加的这个新文件重建。当我关闭应用程序并重新启动时,该文件会显示在我的列表中。

按照这个答案:is it possible to refresh or reload page with navigator.pop... like 1st (nav.push=>2) page to 2nd page and back from 2nd (nav.pop, value) to 1st page? 我将.then()Navigator.push 一起使用并在setState() 中重建了我的列表,但它仍然没有更新。

我做错了什么?以下是我的代码:

class _HomeListViewState extends State<HomeListView> {
  Directory easyDir;
  var txtList;

  @override
  void initState(){
    super.initState();
    easyDir = Directory(widget.folderPath);
    buildTxtList();
  }

  void buildTxtList(){
    //list of paths of my txt files in the folder
    txtList = easyDir
        .listSync()
        .map((item) => item.path)
        .where((item) => item.endsWith(".txt"))
        .toList();
  }

  @override
  Widget build(BuildContext context) {

    print(txtList.length);
    
    return ListView.builder(
      itemCount: txtList.length,
      padding: EdgeInsets.all(10.0),
      itemBuilder: (context, index){
        File file = new File(txtList[index]);
        String name = file.path.split('/').last;
        return Card(
          color: (index % 2 == 0) ? Colors.grey.shade300 : Colors.white,
          shadowColor: Colors.teal,
          elevation: 7.0,
          child: ListTile(
            leading: Icon(Icons.assignment),
            title: Text(name),
            trailing: Icon(Icons.keyboard_arrow_right),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => NoteEditScreen(
                  txtPath: file.path,
                ),
                ),
              ).then((value) {
                setState(() {
                  buildTxtList();
                });
              });
            },
            onLongPress: () => print('list tile long pressed'),
          ),
        );
      },
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    实现此目的的一种方法是向 NoteEditScreen() 传递一个函数,该函数将在主屏幕中触发回调以重建它(我们已经可以使用 buildTxtList函数或仅为它创建一个新函数)

    void buildTxtList() {
        txtList = easyDir
            .listSync()
            .map((item) => item.path)
            .where((item) => item.endsWith(".txt"))
            .toList();
        
        setState(() {}); // To rebuild the Widget
       
      }
    

    然后传下去

    Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => 
                      NoteEditScreen(onPressed: buildTxtList),
                    ),
                       );
    

    然后在NoteEditScreen中,先声明属性,最后在AppBar中调用它。

    注意:您不必调用 AppBar 的 leading 属性中的函数,您可以在他们将笔记保存到文件夹中时调用它。

    final Function onPressed;
      
      NoteEditScreen({this.onPressed});
    
      appBar: AppBar(
          title: Text("Screen 2"),
           leading: IconButton(
            icon: Icon(Icons.arrow_back),
             onPressed: () {
               onPressed();
               Navigator.pop(context);
             }
           )
         ),
    

    注意:您应该绝对看看这两个谈论使用setState(() {})的帖子 Empty set state what is the point?

    Why does setState take a closure?

    【讨论】:

      最近更新 更多