You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Dart网络数据获取问题:输入编码后数据不显示

问题分析与修复方案

核心问题

  1. 异步请求未等待:fetchData是异步方法,点击按钮后直接调用showFetchedData,此时数据还未完成获取,弹窗展示的是空列表。
  2. 未触发UI更新:数据获取成功后没有调用setState(),页面中的列表组件无法感知数据变化,不会自动刷新。
  3. 错误无提示:异步请求的异常未被捕获,无法排查请求失败或数据解析问题。
  4. 键名匹配风险:需确认API返回的字段是否为'next bus'(带空格),若后端返回驼峰/下划线格式(如nextBus/next_bus),会导致文本显示为空。

修复步骤与代码修改

1. 等待异步请求完成

将按钮点击事件改为异步方法,确保数据获取完成后再打开弹窗:

onPressed: () async {
  final query = queryController.text.trim();
  if (query.isEmpty) {
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('请输入公交服务编码')),
    );
    return;
  }
  try {
    await fetchData(query);
    showFetchedData();
  } catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('请求失败: $e')),
    );
  }
},

2. 获取数据后更新UI

在fetchData中调用setState(),触发页面组件刷新:

Future<void> fetchData(String query) async {
  final response = await http.get(
    Uri.parse('https://laravelsyd-fypfinalver.herokuapp.com/getBusService?query=$query')
  );

  if (response.statusCode == 200) {
    final List<dynamic> data = json.decode(response.body);
    setState(() {
      dataList = List<Map<String, dynamic>>.from(data);
    });
  } else {
    throw Exception('HTTP请求失败,状态码: ${response.statusCode}');
  }
}

3. 增加字段空值处理

避免因键名不匹配导致显示异常,增加空值判断:

return ListTile(
  title: Text('Service: ${item['service'] ?? 'N/A'}'),
  subtitle: Text('Next Bus: ${item['next bus'] ?? 'N/A'}'),
);

完整修改代码

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: BusNearby(),
    );
  }
}

// 类名遵循大驼峰命名规范
class BusNearby extends StatefulWidget {
  const BusNearby({super.key});

  @override
  _BusNearbyState createState() => _BusNearbyState();
}

class _BusNearbyState extends State<BusNearby> {
  final TextEditingController queryController = TextEditingController();
  List<Map<String, dynamic>> dataList = [];

  Future<void> fetchData(String query) async {
    final response = await http.get(
      Uri.parse('https://laravelsyd-fypfinalver.herokuapp.com/getBusService?query=$query')
    );

    if (response.statusCode == 200) {
      final List<dynamic> data = json.decode(response.body);
      setState(() {
        dataList = List<Map<String, dynamic>>.from(data);
      });
    } else {
      throw Exception('HTTP请求失败,状态码: ${response.statusCode}');
    }
  }

  void showFetchedData() {
    showModalBottomSheet(
      context: context,
      builder: (BuildContext modalContext) {
        return Container(
          padding: const EdgeInsets.all(16),
          child: dataList.isEmpty
              ? const Center(child: Text('未找到对应数据'))
              : ListView.builder(
                  itemCount: dataList.length,
                  itemBuilder: (_, index) {
                    final item = dataList[index];
                    return ListTile(
                      title: Text('Service: ${item['service'] ?? 'N/A'}'),
                      subtitle: Text('Next Bus: ${item['next bus'] ?? 'N/A'}'),
                    );
                  },
                ),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Data Retrieval Example'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: TextField(
                controller: queryController,
                decoration: const InputDecoration(
                  labelText: 'Enter Bus Service Code',
                ),
              ),
            ),
            ElevatedButton(
              onPressed: () async {
                final query = queryController.text.trim();
                if (query.isEmpty) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('请输入公交服务编码')),
                  );
                  return;
                }
                try {
                  await fetchData(query);
                  showFetchedData();
                } catch (e) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text('请求失败: $e')),
                  );
                }
              },
              child: const Text('Fetch Data'),
            ),
            if (dataList.isNotEmpty)
              SizedBox(
                width: 200,
                height: 100,
                child: ListView.builder(
                  itemCount: dataList.length,
                  itemBuilder: (context, index) {
                    final item = dataList[index];
                    return ListTile(
                      title: Text('Service: ${item['service'] ?? 'N/A'}'),
                      subtitle: Text('Next Bus: ${item['next bus'] ?? 'N/A'}'),
                    );
                  },
                ),
              ),
            const DataTable(
              columns: <DataColumn>[
                DataColumn(label: Text('Service Code')),
                DataColumn(label: Text('Location')),
              ],
              rows: <DataRow>[
                DataRow(cells: <DataCell>[
                  DataCell(Text('1076')),
                  DataCell(Text('Larkin Terminal')),
                ]),
                DataRow(cells: <DataCell>[
                  DataCell(Text('1084')),
                  DataCell(Text('Taman Universiti')),
                ]),
                DataRow(cells: <DataCell>[
                  DataCell(Text('1019')),
                  DataCell(Text('Skudai Prade')),
                ]),
                DataRow(cells: <DataCell>[
                  DataCell(Text('1052')),
                  DataCell(Text('Opposite Skudai Prade')),
                ]),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者katamykenji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 00:34:58