【问题标题】:Flutter Bind Json data in ListView not showing in UIFlutter Bind Json 数据在 ListView 中未显示在 UI 中
【发布时间】:2021-06-25 11:33:43
【问题描述】:

我的 Json 响应状态代码是 200,并且该对象也已创建,但是当我尝试将其与 ListView 中的 UI 绑定时,它不显示任何内容。我还解析了从 json 数据创建的模型。

这是我的 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;
  bool isSearching = false;
  TabController _tabController;

  @override
  void initState() {
    // TODO: implement initState

    super.initState();
    _tabController = TabController(length: 2, initialIndex: 0, vsync: this);
    _tabController.addListener(_handleTabIndex);
  }

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

  void _handleTabIndex() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    _contactsModel = API_Manager().getContacts();
    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: (context, snapshot) {
                      if (snapshot.hasData) {
                        return ListView.builder(
                            padding: const EdgeInsets.all(6),
                            itemCount: snapshot.data.contacts.length,
                            itemBuilder: (context, index) {
                              var contact = snapshot.data.contacts[index];
                              return Container(
                                height: 100,
                                color: Colors.white,
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text(contact.owner.username,
                                        style: TextStyle(fontSize: 16))
                                  ],
                                ),
                              );
                            });
                      } else
                        return Center(child: CircularProgressIndicator());
                    })),
            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',
                              style: TextStyle(fontSize: 16),
                            ),
                            Text(
                              'Example company',
                              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',
                              style: TextStyle(fontSize: 16),
                            ),
                            Text(
                              'example',
                              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,
            ),
          );
  }
}

输出屏幕: ListView should be displayed here

Dart DevTools 网络分析: response code is displayed

Json 查看器: Contacts Json

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",
                    }
                },
                 "...": {
                             "..." : "..."
                            }

【问题讨论】:

  • 我已经用你提供的代码和一个虚拟的 ContactsModel 进行了测试,它工作正常,所以我想知道问题是否出在 ContactsModel - 请添加代码和示例 JSON 字符串。跨度>
  • 验证您的 snapshot.data.contacts 是否为空。
  • 记录您返回的 contactsModel.contacts 并确保它不是空数组。如果是空数组,请在请求完成后捕获您的颤动日志并将其显示给我们
  • @PatrickO'Hara 我已经用示例 json 查看器更新了问题,ContactsModel 文件太大,无法在此处上传。我已经尝试了其他所有方法,但没有运气。你还能帮帮我吗?
  • @Taur 不为空,有 2 个联系人。我已经用 json 查看器的屏幕截图编辑了这个问题。此外,我创建的 contactsModel 来自我通过 quicktype.io 收到的记录的 json 响应

标签: json api flutter dart rest


【解决方案1】:

JSON 有这个:

{
    "total": "187144",
    "contacts": {
        "897": {
            "isPublished": true,
            "id": 897,
            "fields": {

所以你的ContactModel.contacts 是一个Map,由id 值“897”等作为键,而不是List,所以这一行返回null

  var contact = snapshot.data.contacts[index];

(当您引用 contact 的成员时,这应该会引发异常。)您可以像这样对 Map 进行索引:

List keys = snapshot.data.contacts.keys.toList();
List values = snapshot.data.contacts.values.toList();
return ListView.builder(
    padding: const EdgeInsets.all(6),
    itemCount: snapshot.data.contacts.length,
    itemBuilder: (context, index) {
      var contact = values[index];

顺便说一句,API_Manager 中的这一行很奇怪:

contactsModel = contactsModel.fromJson(jsonMap);

它给出了一个空指针异常。当然应该是:

contactsModel = ContactsModel.fromJson(jsonMap);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2021-06-27
    • 2020-12-30
    • 2021-11-27
    • 2021-10-22
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多