从 PHP API 获取数据并在 Flutter Table 中展示

霞舞
发布: 2025-10-18 09:50:01
原创
588人浏览过

从 php api 获取数据并在 flutter table 中展示

本文档将指导你如何从 PHP API 获取数据,并使用 Flutter 的 `Table` 组件将其动态地展示出来。我们将重点解决 `NoSuchMethodError: The getter 'length' was called on null` 错误,并提供清晰的代码示例和注意事项,确保数据正确加载和显示。

从 PHP API 获取数据

首先,确保你已经创建了一个 Flutter 项目,并且已经添加了 http 依赖。你可以在 pubspec.yaml 文件中添加:

dependencies:
  http: ^0.13.0 # 请使用最新版本
登录后复制

然后,运行 flutter pub get 来安装依赖。

接下来,创建一个 Model 类来映射 API 返回的数据。根据你提供的 JSON 示例,已经定义了 Model 和 Tender 类。这里再贴一下,方便查阅:

立即学习PHP免费学习笔记(深入)”;

class Model {
  Model({
    this.id,
    this.goodsRef,
    this.loyer,
    this.bnCode,
    this.loyeeNo,
    this.contactName,
    this.contactTel,
    this.bnDesc,
    this.reqStatus,
    this.eMail,
    this.comments,
    this.tender,
    this.reqDate,
    this.sscOffice,
  });

  final String id;
  final int goodsRef;
  final String loyer;
  final String bnCode;
  final int loyeeNo;
  final dynamic contactName;
  final dynamic contactTel;
  final String bnDesc;
  final String reqStatus;
  final dynamic eMail;
  final String comments;
  final List<Tender> tender;
  final DateTime reqDate;
  final dynamic sscOffice;

  factory Model.fromJson(Map<String, dynamic> json) => Model(
    id: json["\u0024id"] == null ? null : json["\u0024id"],
    goodsRef: json["goods_ref"] == null ? null : json["goods_ref"],
    loyer: json["loyer"] == null ? null : json["loyer"],
    bnCode: json["bn_code"] == null ? null : json["bn_code"],
    loyeeNo: json["loyee_no"] == null ? null : json["loyee_no"],
    contactName: json["contact_name"],
    contactTel: json["contact_tel"],
    bnDesc: json["bn_desc"] == null ? null : json["bn_desc"],
    reqStatus: json["req_status"] == null ? null : json["req_status"],
    eMail: json["e_mail"],
    comments: json["comments"] == null ? null : json["comments"],
    tender: json["tender"] == null ? null : List<Tender>.from(json["tender"].map((x) => Tender.fromJson(x))),
    reqDate: json["req_date"] == null ? null : DateTime.parse(json["req_date"]),
    sscOffice: json["ssc_office"],
  );

  Map<String, dynamic> toJson() => {
    "\u0024id": id == null ? null : id,
    "goods_ref": goodsRef == null ? null : goodsRef,
    "loyer": loyer == null ? null : loyer,
    "bn_code": bnCode == null ? null : bnCode,
    "loyee_no": loyeeNo == null ? null : loyeeNo,
    "contact_name": contactName,
    "contact_tel": contactTel,
    "bn_desc": bnDesc == null ? null : bnDesc,
    "req_status": reqStatus == null ? null : reqStatus,
    "e_mail": eMail,
    "comments": comments == null ? null : comments,
    "tender": tender == null ? null : List<dynamic>.from(tender.map((x) => x.toJson())),
    "req_date": reqDate == null ? null : reqDate.toIso8601String(),
    "ssc_office": sscOffice,
  };
}

class Tender {
  Tender({
    this.id,
    this.goodsRef,
    this.inNo,
    this.tenderNo,
    this.closingDate,
  });

  final String id;
  final int goodsRef;
  final int inNo;
  final String tenderNo;
  final String closingDate;

  factory Tender.fromJson(Map<String, dynamic> json) => Tender(
    id: json["\u0024id"] == null ? null : json["\u0024id"],
    goodsRef: json["goods_ref"] == null ? null : json["goods_ref"],
    inNo: json["in_no"] == null ? null : json["in_no"],
    tenderNo: json["tender_no"] == null ? null : json["tender_no"],
    closingDate: json["closing_date"] == null ? null : json["closing_date"],
  );

  Map<String, dynamic> toJson() => {
    "\u0024id": id == null ? null : id,
    "goods_ref": goodsRef == null ? null : goodsRef,
    "in_no": inNo == null ? null : inNo,
    "tender_no": tenderNo == null ? null : tenderNo,
    "closing_date": closingDate == null ? null : closingDate,
  };
}
登录后复制

接下来,创建一个函数来从 API 获取数据:

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

Future<List<Model>> fetchItems(String email) async {
  String apiurl = "YOUR_API_URL"; // 替换为你的 API URL
  var response = await http.post(Uri.parse(apiurl), body: {
    'username': email // 获取用户名
  });

  if (response.statusCode == 200) {
    // 使用 utf8.decode 处理中文乱码问题
    final decodedBody = utf8.decode(response.bodyBytes);
    List<dynamic> jsonResponse = jsonDecode(decodedBody);
    List<Model> model = jsonResponse.map((item) => Model.fromJson(item)).toList();
    return model;
  } else {
    throw Exception('Failed to load data from API');
  }
}
登录后复制

注意:

  • 将 YOUR_API_URL 替换为你的 PHP API 的实际 URL。
  • 使用了 utf8.decode(response.bodyBytes) 来处理中文乱码问题,确保API返回的编码是UTF-8。

在 Flutter Table 中展示数据

现在,我们可以使用 FutureBuilder 来异步获取数据,并在 Table 组件中展示数据。

class MyTable extends StatefulWidget {
  @override
  _MyTableState createState() => _MyTableState();
}

class _MyTableState extends State<MyTable> {
  String email = "test@example.com"; // 替换为你的邮箱
  Future<List<Model>> _dataFuture;

  @override
  void initState() {
    super.initState();
    _dataFuture = fetchItems(email);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Data Table from API')),
      body: FutureBuilder<List<Model>>(
        future: _dataFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            return Center(child: Text('Error: ${snapshot.error}'));
          } else if (snapshot.hasData) {
            return buildTable(snapshot.data);
          } else {
            return Center(child: Text('No data available'));
          }
        },
      ),
    );
  }

  Widget buildTable(List<Model> data) {
    return SingleChildScrollView( // 确保表格在小屏幕上可以滚动
      scrollDirection: Axis.horizontal,
      child: Table(
        border: TableBorder.all(width: 1, color: Colors.black45),
        columnWidths: {
          0: FixedColumnWidth(100.0), // 可以自定义列宽
          1: FixedColumnWidth(150.0),
          2: FixedColumnWidth(200.0),
          3: FixedColumnWidth(100.0),
        },
        children: [
          TableRow( // 表头
            children: [
              TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text('Goods Ref')))),
              TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text('BN Code')))),
              TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text('BN Desc')))),
              TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text('Req Status')))),
            ],
          ),
          ...data.map((item) {
            return TableRow(
              children: [
                TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text(item.goodsRef?.toString() ?? '')))),
                TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text(item.bnCode ?? '')))),
                TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text(item.bnDesc ?? '')))),
                TableCell(child: Center(child: Padding(padding: EdgeInsets.all(5), child: Text(item.reqStatus ?? '')))),
              ],
            );
          }).toList(),
        ],
      ),
    );
  }
}
登录后复制

关键点:

芦笋演示
芦笋演示

一键出成片的录屏演示软件,专为制作产品演示、教学课程和使用教程而设计。

芦笋演示34
查看详情 芦笋演示
  • 使用 FutureBuilder 来处理异步数据加载。
  • 在 buildTable 方法中,使用 data.map 来迭代数据并创建 TableRow。
  • 使用 item.propertyName ?? '' 来处理可能为 null 的值,避免 NoSuchMethodError 错误。 ?? 是 Dart 的 null-aware 运算符,如果 item.propertyName 为 null,则使用空字符串 '' 作为默认值。
  • SingleChildScrollView 确保表格在小屏幕上可以滚动。
  • 添加了表头,使表格更易于理解。
  • 使用 columnWidths 来自定义列宽。

解决 NoSuchMethodError 错误

NoSuchMethodError: The getter 'length' was called on null 错误通常发生在尝试访问 null 值的属性时。在你的例子中,这很可能是因为 API 返回的数据中某些字段是 null,而你没有正确处理。

解决方法:

  1. 使用 null-aware 运算符 (??): 在访问可能为 null 的属性时,使用 ?? 运算符提供一个默认值。例如:Text(item.name ?? '')。

  2. 检查 null 值: 在访问属性之前,可以使用 if (item.property != null) 来检查值是否为 null。

  3. 在 Model 类中处理 null 值: 在 Model 类的 fromJson 方法中,可以为可能为 null 的字段提供默认值。例如:

    factory Model.fromJson(Map<String, dynamic> json) => Model(
      // ...
      bnDesc: json["bn_desc"] == null ? "" : json["bn_desc"],
      // ...
    );
    登录后复制

总结

本文档介绍了如何从 PHP API 获取数据,并在 Flutter 的 Table 组件中展示数据。通过使用 FutureBuilder、null-aware 运算符和适当的错误处理,你可以创建一个动态的、数据驱动的表格。记住,处理 API 返回的 null 值是避免 NoSuchMethodError 错误的关键。希望本教程能够帮助你成功地构建你的 Flutter 应用!

以上就是从 PHP API 获取数据并在 Flutter Table 中展示的详细内容,更多请关注php中文网其它相关文章!

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号