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

Flutter中如何从JSON文件获取数据填充GridView.builder?

用JSON中MORE_APPS数据填充GridView.builder的实现方案

步骤1:定义数据模型类

先创建对应MORE_APPS数组元素的模型类,方便数据管理:

class MoreApp {
  final String title;
  final String img;
  final String url;
  final String country;

  MoreApp({
    required this.title,
    required this.img,
    required this.url,
    required this.country,
  });

  // 从JSON对象转换为模型实例
  factory MoreApp.fromJson(Map<String, dynamic> json) {
    return MoreApp(
      title: json['title'] ?? '',
      img: json['img'] ?? '',
      url: json['url'] ?? '',
      country: json['country'] ?? '',
    );
  }
}

步骤2:加载并解析JSON数据

根据你的JSON来源(本地资产或网络)选择对应方式:

方式1:加载本地JSON文件

  1. 先在pubspec.yaml中配置资产路径:
flutter:
  assets:
    - assets/your_data.json # 替换成你的JSON文件实际路径
  1. 编写加载解析函数:
import 'dart:convert';
import 'package:flutter/services.dart';

Future<List<MoreApp>> loadLocalMoreApps() async {
  // 读取本地JSON文件内容
  final String jsonString = await rootBundle.loadString('assets/your_data.json');
  final Map<String, dynamic> data = json.decode(jsonString);
  // 提取MORE_APPS数组并转换为模型列表
  List<dynamic> moreAppsJson = data['MORE_APPS'];
  return moreAppsJson.map((appJson) => MoreApp.fromJson(appJson)).toList();
}

方式2:从网络加载JSON数据

  1. 先在pubspec.yaml添加http依赖:
dependencies:
  flutter:
    sdk: flutter
  http: ^1.1.0
  1. 编写网络请求解析函数:
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<List<MoreApp>> fetchRemoteMoreApps() async {
  final response = await http.get(Uri.parse('你的JSON文件网络地址'));
  if (response.statusCode == 200) {
    final Map<String, dynamic> data = json.decode(response.body);
    List<dynamic> moreAppsJson = data['MORE_APPS'];
    return moreAppsJson.map((appJson) => MoreApp.fromJson(appJson)).toList();
  } else {
    throw Exception('加载数据失败');
  }
}

步骤3:用GridView.builder展示数据

结合FutureBuilder处理异步加载状态,最终实现网格视图:

import 'package:flutter/material.dart';

class MoreAppsGrid extends StatefulWidget {
  const MoreAppsGrid({super.key});

  @override
  State<MoreAppsGrid> createState() => _MoreAppsGridState();
}

class _MoreAppsGridState extends State<MoreAppsGrid> {
  late Future<List<MoreApp>> _moreAppsFuture;

  @override
  void initState() {
    super.initState();
    // 选择本地加载或网络加载
    _moreAppsFuture = loadLocalMoreApps();
    // _moreAppsFuture = fetchRemoteMoreApps();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<MoreApp>>(
      future: _moreAppsFuture,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          final List<MoreApp> moreApps = snapshot.data!;
          return GridView.builder(
            padding: const EdgeInsets.all(16),
            // 网格布局配置:每行2个,设置间距和宽高比
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              crossAxisSpacing: 16,
              mainAxisSpacing: 16,
              childAspectRatio: 0.8,
            ),
            itemCount: moreApps.length,
            itemBuilder: (context, index) {
              final MoreApp app = moreApps[index];
              return Card(
                elevation: 2,
                child: Column(
                  children: [
                    // 加载应用图片,处理加载失败场景
                    Expanded(
                      child: Image.network(
                        app.img,
                        fit: BoxFit.cover,
                        errorBuilder: (context, error, stackTrace) {
                          return const Icon(Icons.broken_image, size: 40);
                        },
                      ),
                    ),
                    // 应用标题
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 8),
                      child: Text(
                        app.title,
                        textAlign: TextAlign.center,
                        style: const TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 14,
                        ),
                      ),
                    ),
                    // 跳转按钮(需添加url_launcher依赖实现跳转)
                    TextButton(
                      onPressed: () {
                        // 示例:打开应用链接
                        // launchUrl(Uri.parse(app.url));
                      },
                      child: const Text('获取应用'),
                    ),
                  ],
                ),
              );
            },
          );
        } else if (snapshot.hasError) {
          return Center(child: Text('加载出错:${snapshot.error}'));
        }
        // 加载中状态
        return const Center(child: CircularProgressIndicator());
      },
    );
  }
}

注意事项

  1. JSON格式修正:你提供的JSON末尾有多余的逗号("MORE_APPS": [...],中的逗号),需要删除,否则会导致解析失败。
  2. 链接跳转实现:如果需要点击按钮打开链接,需添加url_launcher依赖,并在Android/iOS项目中配置相应权限。
  3. 图片加载优化:如果图片是本地资产,需将Image.network替换为Image.asset,并确保图片路径正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:45:47