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

Flutter动态JSON展示:如何并列显示AppDetails的键与对应数据

Flutter动态展示appDetails下所有键值对的实现示例

核心思路

因为appDetails的键是动态变化的,但字段本身固定存在,所以可以将其转为Map<String, dynamic>后,遍历所有键值对,根据值的类型(字符串、列表等)动态渲染对应的UI组件。

示例代码

以下是完整的可运行示例,包含模拟数据、键名格式化、多类型值渲染:

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('App Details展示')),
        body: const AppDetailsView(),
      ),
    );
  }
}

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

  // 模拟接口返回的动态JSON数据
  final Map<String, dynamic> productData = {
    "productName": "智能办公系统",
    "appDetails": {
      "systemOverview": "这是一套集成了文档管理、协作沟通的智能办公平台,提升团队效率。",
      "benefits": ["降低沟通成本", "提升文档安全性", "简化审批流程"],
      "mainFeatures": ["实时协作编辑", "多级权限管理", "跨设备同步"],
      "usageScenarios": "适用于中小团队、企业远程办公、项目协作等场景"
    }
  };

  @override
  Widget build(BuildContext context) {
    // 提取appDetails核心数据
    final Map<String, dynamic> appDetails = productData['appDetails'];

    return Padding(
      padding: const EdgeInsets.all(16.0),
      // 用ListView实现滚动展示
      child: ListView.builder(
        itemCount: appDetails.entries.length,
        itemBuilder: (context, index) {
          final entry = appDetails.entries.elementAt(index);
          final key = entry.key;
          final value = entry.value;

          return Padding(
            padding: const EdgeInsets.only(bottom: 20.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                // 格式化后的键名标题
                Text(
                  _formatKeyName(key),
                  style: const TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                    color: Colors.blueAccent,
                  ),
                ),
                const SizedBox(height: 8),
                // 根据值类型渲染对应组件
                _buildValueWidget(value),
              ],
            ),
          );
        },
      ),
    );
  }

  // 将驼峰命名的键转为友好的标题(如systemOverview → 系统概述)
  String _formatKeyName(String key) {
    final formatted = key.replaceAllMapped(
      RegExp(r'([A-Z])'),
      (match) => ' ${match.group(0)}',
    );
    return formatted[0].toUpperCase() + formatted.substring(1);
  }

  // 根据值的类型返回对应UI组件
  Widget _buildValueWidget(dynamic value) {
    if (value is List) {
      // 列表类型渲染带项目符号的列表
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: value.map((item) {
          return Padding(
            padding: const EdgeInsets.symmetric(vertical: 4.0),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text('• ', style: TextStyle(fontSize: 16)),
                Expanded(child: Text(item.toString(), style: const TextStyle(fontSize: 16))),
              ],
            ),
          );
        }).toList(),
      );
    } else if (value is String) {
      // 字符串类型直接展示
      return Text(value, style: const TextStyle(fontSize: 16, height: 1.5));
    } else {
      // 其他类型(数字、布尔值等)转为字符串展示
      return Text(value.toString(), style: const TextStyle(fontSize: 16));
    }
  }
}

关键说明

  1. 遍历键值对:通过appDetails.entries获取所有键值对,用ListView.builder动态生成每一项
  2. 键名格式化:_formatKeyName方法将驼峰命名的键转为易读的标题,可根据需求调整格式规则
  3. 多类型适配:_buildValueWidget方法根据值的类型(列表、字符串等)渲染不同UI,若有嵌套Map等复杂结构,可在此方法中添加递归处理逻辑
  4. 异步数据适配:如果数据来自网络请求,只需将示例中的模拟数据替换为FutureBuilder或状态管理中的异步数据即可

扩展提示

  • 可根据设计需求添加卡片容器、阴影、自定义间距等样式优化
  • 若需支持更多数据类型(如嵌套对象),只需在_buildValueWidget中新增对应类型的处理分支

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:05:18