当我更新 ListView 上的列表时,Flutter 页面不会重新加载

Posted

技术标签:

【中文标题】当我更新 ListView 上的列表时,Flutter 页面不会重新加载【英文标题】:Flutter page does not reload when I update the list on the ListView 【发布时间】:2021-08-04 01:14:24 【问题描述】:

抱歉,问题可能很小。

所以我得到了这个文件

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../utils/authentication.dart';
import '../utils/stated.dart';
import 'user_info_screen.dart';


class CategoryScreen extends StatefulWidget 
  const CategoryScreen(Key? key, required User user, required Stated stated, required int intel)
      : _user = user, _stated = stated, _intel = intel,
        super(key: key);

  final User _user;
  final Stated _stated;
  final int _intel;

  @override
  _CategoryScreenState createState() => _CategoryScreenState();


class _CategoryScreenState extends State<CategoryScreen> 
  late User _user;
  late Stated _stated;
  late int _intel;
  bool loaded = false;
  List<Widget> rows = [];
  int limit = 2;
  var temporal = ;

  @override
  void initState() 
    _user = widget._user;
    _stated = widget._stated;
    _intel = widget._intel;
    super.initState();

  

  @override
  Widget build(BuildContext context) 
    //print(_user.photoURL);

    if (!loaded) 
      print(rows.toString());
      setState(() 
        // Rows ==============================================================================================================

        FirebaseFirestore.instance.collection('listings').where('category', isEqualTo: _stated.CATEGORIES[_intel]).orderBy('views', descending: true).limit(limit).get().then((value) 

          rows.add(
              Padding(
                padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0, left: 16.0),
                child: Text(
                  _stated.CATEGORIES[_intel],
                  style: TextStyle(
                    fontSize: 30,
                    color: Colors.white,
                    letterSpacing: 2,
                  ),
                ),
              )
          );
          value.docs.forEach((element) 
            if (element.data()['reviewed'] == false) 

              rows.add(
                  Container(
                    height: 30.0,
                  )
              );
              rows.add(
                  OutlineButton(
                      onPressed: () async 
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => DisplayScreen(
                              user: _user,
                              stated: _stated,
                              intel: element.id,
                            ),
                          ),
                        );
                      ,
                      child: Column(
                        children: <Widget> [
                          Container(
                            height: 175.0,
                            width: 200,
                            child: Image.network(element.data()['image']['0']),
                          ),
                          Container(
                            height: 75.0,
                            width: 200,
                            child: Padding(
                              padding: EdgeInsets.only(top: 10.0, bottom: 10.0, right: 16.0, left: 16.0),
                              child: Center(
                                child: Text(
                                  element.data()['title'],
                                  style: TextStyle(
                                    fontSize: 15,
                                    color: Colors.white,
                                    letterSpacing: 2,
                                  ),
                                ),
                              ),
                            ),
                          ),

                        ],
                      )
                  )
              );
            
          );
        ).then((e) 
          loaded = true;
          print(rows.toString());
          if (rows.length == limit) 
            rows.add(
                Container(
                  height: 30.0,
                )
            );
            rows.add(
                OutlineButton(
                    onPressed: () async 

                    ,
                    child: Column(
                      children: <Widget> [
                        Container(
                          height: 250.0,
                          width: 200,
                          child: Padding(
                            padding: EdgeInsets.only(top: 10.0, bottom: 10.0, right: 16.0, left: 16.0),
                            child: Center(
                              child: Text(
                                'Load More',
                                style: TextStyle(
                                  fontSize: 15,
                                  color: Colors.white,
                                  letterSpacing: 2,
                                ),
                              ),
                            ),
                          ),
                        ),

                      ],
                    )
                )
            );
          
        );
      );
      // End of setState =============================================================
    
    return Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
          elevation: 0,
          backgroundColor: Colors.black,
          actions: <Widget>[
            ElevatedButton(
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.black),
                shape: MaterialStateProperty.all(
                  RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(40),
                  ),
                ),
              ),
              onPressed: () async 

                User? user =
                await Authentication.signInWithGoogle(context: context);

                if (user != null) 
                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) => UserInfoScreen(
                        user: user,
                      ),
                    ),
                  );
                
              ,
              child: Padding(
                padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                child: _user.photoURL != null
                    ? ClipOval(
                  child: Material(
                    color: Colors.black.withOpacity(0.3),
                    child: Image.network(
                      (_user.photoURL!).replaceAll("=s96-c", "=s1000-c"),
                      height: 50.0,
                    ),
                  ),
                )
                    : ClipOval(
                  child: Material(
                    color: Colors.black.withOpacity(0.3),
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Icon(
                        Icons.person,
                        size: 50,
                        color: Colors.grey,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ],
        ),
        body: Center(
          child: ListView(
            shrinkWrap: true,
            padding: EdgeInsets.all(10.0),
            children: rows,
          ),
        )
    );
  

页面加载正常,没有错误,但是页面的概念是我的应用程序的“类别”页面,想法是一旦重新路由到此页面,我创建一个列表视图以不将屏幕留空,然后运行加载项目的 Firebase 调用,当前设置为 2 个项目的限制(用于测试),我创建了类似卡片的容器来保存项目的数据。

问题是列表中的所有项目都存储在“行”中,并且当我通过在控制台上打印它进行检查时会更新此变量,但是屏幕上的页面不会更新。

我确实相信这是我忘记/遗漏的常见或基本的事情,因为没有错误,或者我可能是如何设置列表的,但是每次我在网上搜索这个问题时,没有人遇到过这个问题。

如何在屏幕上显示列表?

PS:就像 android studio 一样,如果我按下 CTRL-S 来保存代码,它也会热重载模拟器,并且在模拟器中的一瞬间,列表会显示出来。

【问题讨论】:

【参考方案1】:

build 方法中有很多业务逻辑会阻塞你的 UI 渲染,直到你从 Firestore 获得结果 - 这很糟糕,绝对不是一个可行的方法。

您应该首先了解有关 FutureBuilder 或任何状态管理解决方案的更多信息,以检索数据并根据状态更改构建 UI。我建议从这个 Codelab(或任何其他 Firestore + Flutter 教程)开始,以了解如何在 Flutter 中使用 Firestore:https://firebase.google.com/codelabs/firebase-get-to-know-flutter

【讨论】:

你是对的,不是很明白,但是在看到这个例子后我得到了备忘录***.com/questions/54385713/…

以上是关于当我更新 ListView 上的列表时,Flutter 页面不会重新加载的主要内容,如果未能解决你的问题,请参考以下文章

uiautomator - 当我验证每个列表项中的文本时,无法让 ListView 滚动。当我点击屏幕上的最后一个项目时它就失败了

Flutter ListView 不会更新

在 Flutter 中构建列表项时如何更新 ListView.builder 的 itemCount?

Android ListView 更新颜色

使用应用程序更新 ListView 小部件

VideoView 上的透明 ListView