在 Json 数据中更新后未显示 ListView

Posted

技术标签:

【中文标题】在 Json 数据中更新后未显示 ListView【英文标题】:ListView not displayed after update in Json Data 【发布时间】:2021-06-27 03:32:40 【问题描述】:

状态响应代码为 200,但 ListView 未显示并卡在 CircularProgressIndicator 上。 当我在 Json 数据中有 2 个项目时,它显示得很好,但是当我添加另一个项目时,它没有显示出来! 我尝试删除 ListView.separated 并改用 ListView.builder 并尝试使用 StreamBuilder 但我似乎没有正确使用它,因为我对 Flutter 还很陌生。如果我必须使用 StreamBuilder,我可以在这里指导如何正确使用它吗?谢谢。

这是我的 API_manager.dart 文件:

import 'package:http/http.dart' as http;
import 'package:aritic/models/contactsModel.dart';

// ignore: camel_case_types
class API_Manager 
  Future<ContactsModel> getContacts() async 
    var client = http.Client();
    var contactsModel;
    String contacts_url =
        'https://exampleapi.com';
    String basicAuth = 'Basic auth key example';
    try 
      var response = await client.get(contacts_url,
          headers: <String, String>'authorization': basicAuth);
      print(response.statusCode);
      if (response.statusCode == 200) 
        var jsonString = response.body;
        var jsonMap = json.decode(jsonString);
        contactsModel = ContactsModel.fromJson(jsonMap);
      
     catch (Exception) 
      return contactsModel;
    
    return contactsModel;
  

我的用户界面代码:

import 'package:aritic/models/contactsModel.dart';
import 'package:aritic/services/api_manager.dart';

class ContactsPage extends StatefulWidget 
  @override
  _ContactsPageState createState() => _ContactsPageState();


class _ContactsPageState extends State<ContactsPage>
    with SingleTickerProviderStateMixin 
  Future<ContactsModel> _contactsModel;
  TabController _tabController;

  @override
  void initState() 
    // TODO: implement initState
    super.initState();
    _tabController = TabController(length: 2, initialIndex: 0, vsync: this);
    _tabController.addListener(_handleTabIndex);
    _contactsModel = API_Manager().getContacts();
  

  @override
  void dispose() 
    _tabController.removeListener(_handleTabIndex);
    _tabController.dispose();
    super.dispose();
  

  void _handleTabIndex() 
    setState(() );
  

  @override
  Widget build(BuildContext context) 
    return DefaultTabController(
        length: 2,
        child: Scaffold(
          appBar: AppBar(
            title: Text('Contacts'),
            bottom: PreferredSize(
                child: Align(
                  alignment: Alignment.centerLeft,
                  child: TabBar(
                    controller: _tabController,
                    isScrollable: true,
                    unselectedLabelColor: Colors.white.withOpacity(0.3),
                    indicatorColor: Colors.white,
                    tabs: [
                      Tab(
                        child: Text('Contacts'),
                      ),
                      Tab(
                        child: Text('Companies'),
                      )
                    ],
                  ),
                ),
                preferredSize: Size.fromHeight(40.0)),
            actions: <Widget>[
              Padding(
                padding: const EdgeInsets.only(right: 16.0),
                child: IconButton(
                  icon: Icon(Icons.search),
                  color: Colors.white,
                  onPressed: () ,
                ),
              ),
            ],
          ),
          body: TabBarView(controller: _tabController, children: <Widget>[
            Container(
                height: double.infinity,
                child: FutureBuilder<ContactsModel>(
                    future: _contactsModel,
                    builder: (BuildContext context,
                        AsyncSnapshot<ContactsModel> snapshot) 
                      if (snapshot.hasData) 
                        return ListView.separated(
                          shrinkWrap: true,
                          padding: const EdgeInsets.all(6),
                          itemCount: snapshot.data.contacts.length,
                          itemBuilder: (BuildContext context, int index) 
                            List keys = snapshot.data.contacts.keys.toList();
                            List values =
                                snapshot.data.contacts.values.toList();
                            var contact = values[index];
                            return InkWell(
                              onTap: () 
                                Navigator.push(context,
                                    MaterialPageRoute(builder: (_) => ViewContact()));
                              ,
                              child: Container(
                                height: 50,
                                color: Colors.white,
                                child: Column(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text(
                                      contact.owner.firstName +
                                          " " +
                                          contact.owner.lastName,
                                      style: TextStyle(fontSize: 16),
                                    ),
                                    Text(
                                      contact.owner.username,
                                      style: TextStyle(fontSize: 14),
                                    ),
                                    SizedBox(
                                      height: 5,
                                    ),
                                  ],
                                ),
                              ),
                            );
                          ,
                          separatorBuilder: (BuildContext context, int index) 
                             return SizedBox(
                              height: 5,
                            );
                          ,
                        );
                       else
                        return Center(
                            child: CircularProgressIndicator(
                                backgroundColor: Colors.blueGrey[700],
                                valueColor: AlwaysStoppedAnimation<Color>(
                                    Colors.cyan)));
                    )),
            Container(
                height: double.infinity,
                child: ListView(
                  padding: const EdgeInsets.all(6),
                  children: <Widget>[
                    InkWell(
                      onTap: () 
                        Navigator.push(context,
                            MaterialPageRoute(builder: (_) => ViewCompany()));
                      ,
                      child: Container(
                        height: 50,
                        color: Colors.white,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text(
                              'example company name',
                              style: TextStyle(fontSize: 16),
                            ),
                            Text(
                              'example company domain',
                              style: TextStyle(fontSize: 14),
                            )
                          ],
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 5,
                    ),
                    InkWell(
                      onTap: () 
                        Navigator.push(context,
                            MaterialPageRoute(builder: (_) => ViewCompany()));
                      ,
                      child: Container(
                        height: 50,
                        color: Colors.white,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Text(
                              'example company name',
                              style: TextStyle(fontSize: 16),
                            ),
                            Text(
                              'example company domain',
                              style: TextStyle(fontSize: 14),
                            )
                          ],
                        ),
                      ),
                    ),
                  ],
                )),
          ]),
          floatingActionButton: _bottomButtons(),
        ));
  

  Widget _bottomButtons() 
    return _tabController.index == 0
        ? FloatingActionButton(
            shape: StadiumBorder(),
            onPressed: () 
              Navigator.push(context, MaterialPageRoute(builder: (_) 
                return AddContacts();
              ));
            ,
            backgroundColor: Colors.cyan,
            child: Icon(
              Icons.person_add,
              color: Colors.white,
            ))
        : FloatingActionButton(
            shape: StadiumBorder(),
            onPressed: () 
              Navigator.push(context, MaterialPageRoute(builder: (_) 
                return AddCompany();
              ));
            ,
            backgroundColor: Colors.cyan,
            child: Icon(
              Icons.add,
              color: Colors.white,
            ),
          );
  

Json 示例(完整的 json 太大,无法在此处上传):


    "total": "187144",
    "contacts": 
        "897": 
            "isPublished": true,
        "id": 897,
            "fields": 
                "core": 
                    "points": 
                        "id": "47",
                        "label": "Points"
                    ,
                    "firstname": 
                        "id": "2",
                        "label": "First Name",
                        "value": "Jason"
                    ,
                    "lastname": 
                        "id": "3",
                        "label": "Last Name",
                        "value": "Lamuda"
                    ,
                    "...": 
                             "..." : "..."
                            
                ,
            "ipAddresses": [
                
                    "ip": "70.127.91.131",
                    "ipDetails": 
                        "city": "Bradenton",
                        "region": "Florida",
                        "timezone": "America/New_York",
                    
                ,
                 "...": 
                             "..." : "..."
                            

输出屏幕(卡在 CircularProgressIndicator 上): here

【问题讨论】:

而不是 future: _contactsModel,future: API_Manager().getContacts(), 那样做 分享这个contactsModel = ContactsModel.fromJson(jsonMap);和带有新添加元素的json。如果它之前可以工作,但在您添加新内容后停止,则问题将出在已添加的新内容上。 @Reign 不起作用,我只是提供了一个更新的 json 并创建了新的 contactsModel,它显示了第三项,但是当我添加另一个第四项时仍然是同样的问题。 @HuthaifaMuayyad json 超过 30000 个字符,我无法在此处上传,我只是提供了一个更新的 json 并创建了新的 contactsModel,它显示了第 3 项,但是当我又添加了第 4 项时项目仍然是同样的问题。 【参考方案1】:

创建一个类似的函数

Future getContacts()async
      _contactsModel = API_Manager().getContacts();
 

然后在你的 initState 中

getContacts().then((value)
  setState(());
 )

【讨论】:

NoSuchMethodError: The method 'then' was called on null. Receiver: null Tried calling: then&lt;Null&gt;(Closure:(dynamic) =&gt; Null) 嗨,我在函数中添加了async,错误消失了,但我的问题没有解决,仍然卡在CircularProgressIndicator @ShreyasBhardwaj 将 future: _contactsModel, 更改为 future:getContacts(),

以上是关于在 Json 数据中更新后未显示 ListView的主要内容,如果未能解决你的问题,请参考以下文章

重新加载数据后根据要求更新后未显示 uicollectionview 单元格

React Native:更新数据后未重新渲染组件

Android获取服务器Json字符串并显示在ListView上面

从 MySQL 获取数据并使用 JSON 在 ListView 中显示

我想在 Flutter App 的 Listview 中显示我的 Json 数据

无法加载 JSON 数据以在 ListView 中显示