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

Flutter如何在ListView.builder中正确展示嵌套结构的JSON数据

第一步:调整API接口返回值

你当前的接口只返回了PartnerData列表,但DietName存放在接口响应的根级别Data对象中,不属于PartnerDatum的属性,所以首先要修改接口返回完整的模型对象,同时修复现有代码的小问题:

// 修改返回类型为DietDetailsModel
Future<DietDetailsModel> dietcianDetailsApi() async {
  var response = await http.post(
      Uri.parse("http://myapin/api/api/DietDetails"),
      body: ({
        'EncId': 'pEl2tetIxLJO76eQ==' // 修复两个问题:原key末尾多了空格、参数值要包裹引号
      }));
  if (response.statusCode == 200) {
    DietDetailsModel dataModel = dietDetailsModelFromJson(response.body);
    // 原代码print(arrData[1].partnerName)会报错:你的示例JSON里PartnerData只有1个元素,索引从0开始,最多访问到arrData[0]
    return dataModel;
  } else {
    throw Exception("Faild to fetch");
  }
}

第二步:调整FutureBuilder逻辑,展示三层嵌套数据

现在接口返回完整的DietDetailsModel,你可以先在列表外层展示DietName,再在每个列表项里展示PartnerName、合作伙伴信息,以及DayList里的所有可预约日期:

Container(
  height: blockSizeVertical*30,
  child: FutureBuilder<DietDetailsModel>(
    future: dietcianDetailsApi(),
    builder: (BuildContext context, AsyncSnapshot<DietDetailsModel> snapshot) {
      if (snapshot.hasError) {
        return Text("Somthing went wrong");
      }
      if (snapshot.hasData) {
        final dietData = snapshot.data!;
        return Column(
          children: [
            // 最外层展示DietName
            Text(
              dietData.data.dietName,
              style: TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: blockSizeHorizontal*4,
              ),
            ),
            SizedBox(height: 10),
            Expanded(
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                physics: BouncingScrollPhysics(),
                shrinkWrap: true,
                itemCount: dietData.partnerData.length,
                itemBuilder: (BuildContext context, int index) {
                  final partner = dietData.partnerData[index];
                  // 把DayList的日期拼接成字符串,也可以嵌套ListView逐个展示时段
                  final availableDays = partner.dayList.map((day) => day.dayName).join("、");
                  return Container(
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10),
                    ),
                    width: blockSizeHorizontal*80,
                    margin: EdgeInsets.all(10),
                    child: Stack(children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          SizedBox(height: blockSizeVertical*0.5),
                          Text(
                            partner.partnerName,
                            style: TextStyle(
                              fontWeight: FontWeight.bold,
                              fontSize: blockSizeHorizontal*3.5,
                              fontFamily: 'Poppins',
                              color: Theme.of(context).primaryColor,
                            ),
                            textAlign: TextAlign.center,
                          ),
                          SizedBox(height: blockSizeVertical*0.8),
                          Container(
                            padding: EdgeInsets.symmetric(horizontal: 10),
                            child: Center(
                              child: Column(
                                children: [
                                  Text(
                                    '地址:${partner.partnerAddress}\n费用:${partner.fee} 优惠后:${partner.discountedFee}',
                                    style: TextStyle(
                                        fontFamily: 'Poppins',
                                        fontSize: blockSizeHorizontal*2.5,
                                        color: Theme.of(context).primaryColor),
                                    textAlign: TextAlign.center,
                                    maxLines: 4,
                                  ),
                                  SizedBox(height: 5),
                                  // 展示拼接好的可预约日期
                                  Text(
                                    '可预约日期:$availableDays',
                                    style: TextStyle(
                                        fontFamily: 'Poppins',
                                        fontSize: blockSizeHorizontal*2.3,
                                        color: Colors.grey[700]),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        ]
                      ),
                      Positioned(
                        bottom: 5,
                        left: 2,
                        child: Padding(
                          padding: const EdgeInsets.only(left:15.0, bottom: 5),
                          child: InkWell(
                            onTap: () {},
                            child: Container(
                              alignment: Alignment.center,
                              height: blockSizeVertical*5,
                              width: blockSizeHorizontal*30,
                              decoration: BoxDecoration(
                                shape: BoxShape.rectangle,
                                borderRadius: BorderRadius.circular(10),
                                gradient: LinearGradient(
                                  begin: Alignment.topLeft,
                                  end: Alignment.topRight,
                                  colors: [
                                    Theme.of(context).primaryColor,
                                    Theme.of(context).accentColor
                                  ],
                                ),
                              ),
                              child: Text(
                                'Show Details',
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: blockSizeHorizontal*2.7,
                                  fontWeight: FontWeight.bold,
                                  fontFamily: 'Poppins',
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ]),
                  );
                },
              ),
            )
          ],
        );
      }
      return CircularProgressIndicator();
    },
  ),
)

如果需要单独展示每个日期的具体时段,在对应位置嵌套Column或者ListView.builder遍历partner.dayList的元素即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:39:02