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

Flutter中如何在ListView内根据地址数量动态生成卡片盒子

实现思路

你当前的代码中地址、经纬度、图片资源都是硬编码的,要适配服务端动态返回的数据,按下面几个步骤调整即可:

1. 改造Centres实体类

你现在的Centres类是用静态常量写死的,首先要改成可承载服务端返回数据的结构,除了地址外还要包含卡片需要用到的图片链接、纬度、经度等字段:

class Centre {
  final String address;
  final double lat;
  final double lng;
  final String imageUrl;
  // 后续需要其他字段(比如评分、营业时间)也可以直接在这里补充

  Centre({
    required this.address,
    required this.lat,
    required this.lng,
    required this.imageUrl,
  });

  // 新增fromJson方法,方便将服务端返回的json数据直接转成实体对象
  factory Centre.fromJson(Map<String, dynamic> json) {
    return Centre(
      address: json['address'] as String,
      lat: json['lat'] as double,
      lng: json['lng'] as double,
      imageUrl: json['image_url'] as String,
    );
  }
}

2. 在页面State中新增数据状态和请求逻辑

你的Map页面是StatefulWidget,直接在状态类里添加变量存储返回的点位数据,同时补充加载、错误状态,页面初始化的时候调用接口拉取服务端数据:

class _MapState extends State<Map> {
  // 原有代码保持不变,新增以下变量
  List<Centre> centreList = [];
  bool isLoading = true;
  String? errorMsg;

  @override
  void initState() {
    super.initState();
    // 页面初始化时触发服务端数据拉取
    fetchCentresFromServer();
  }

  // 服务端数据请求方法
  Future<void> fetchCentresFromServer() async {
    try {
      // 这里替换为你自己封装的json_service中的实际接口请求方法
      final response = await yourApiRequestMethod();
      // 将接口返回的json数组转成Centre实体列表
      List<Centre> list = (response as List).map((item) => Centre.fromJson(item)).toList();
      setState(() {
        centreList = list;
        isLoading = false;
      });
    } catch (e) {
      setState(() {
        errorMsg = e.toString();
        isLoading = false;
      });
    }
  }

  // 原有代码保持不变...

3. 将硬编码的横向ListView改为动态构建

你现在_buildContainer方法里手动写了3个卡片,替换为ListView.builder动态生成即可,有多少条服务端返回的数据就会自动生成多少个卡片,同时补充加载、错误状态的适配:

// 注意要把_buildContainer方法移动到_MapState类内部,否则无法访问centreList状态数据
Widget _buildContainer() {
  if (isLoading) {
    return const Align(
      alignment: Alignment.bottomLeft,
      child: Padding(
        padding: EdgeInsets.all(20.0),
        child: CircularProgressIndicator(),
      ),
    );
  }
  if (errorMsg != null) {
    return Align(
      alignment: Alignment.bottomLeft,
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Text('加载失败:$errorMsg'),
      ),
    );
  }
  return Align(
    alignment: Alignment.bottomLeft,
    child: Container(
      margin: const EdgeInsets.symmetric(vertical: 20.0),
      height: 150.0,
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        itemCount: centreList.length, // 卡片数量和服务端返回的点位数量完全一致
        itemBuilder: (context, index) {
          final centre = centreList[index];
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            child: _boxes(
              centre.imageUrl,
              centre.lat,
              centre.lng,
              centre.address,
            ),
          );
        },
      ),
    ),
  );
}

注意事项

  • 原来定义的_buildContainer、_boxes、myDetailsContainer1都是顶层函数,需要移动到_MapState类内部,或者把centreList作为参数传递,否则无法访问状态数据
  • 服务端返回的字段名要和Centre类fromJson方法里的key对应,如果字段名不一致自己调整对应关系即可
  • 如果需要实现点击卡片跳转到地图对应点位的功能,直接在_boxes的onTap回调里调用地图控制器的animateCamera方法,传入对应centre的经纬度参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 20:15:06