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

如何通过自定义Widget控制器维护PlutoGrid状态并实现API数据填充?

为PlutoGrid实现自定义控制器并通过API填充数据的示例

前置依赖

在pubspec.yaml中添加所需依赖:

dependencies:
  flutter:
    sdk: flutter
  pluto_grid: ^7.0.0
  http: ^1.1.0
  provider: ^6.0.5

核心逻辑

自定义控制器的核心是把PlutoGrid的数据加载、状态维护、操作逻辑从UI层抽离,减少冗余代码。我们用ChangeNotifier实现控制器,封装API请求、JSON转模型、Pluto行数据转换等核心操作,让UI层仅关注渲染和状态绑定。

步骤1:定义数据模型类

创建对应API返回数据的模型,包含序列化方法:

class User {
  final int id;
  final String name;
  final String email;

  User({required this.id, required this.name, required this.email});

  // 从JSON转模型实例
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'],
      name: json['name'],
      email: json['email'],
    );
  }
}

步骤2:实现自定义PlutoGrid控制器

封装数据请求、转换和Grid状态管理:

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

class CustomPlutoGridController extends ChangeNotifier {
  List<PlutoRow> rows = [];
  bool isLoading = false;
  String? errorMessage;

  // 预定义PlutoGrid列配置
  final List<PlutoColumn> columns = [
    PlutoColumn(
      title: 'ID',
      field: 'id',
      type: PlutoColumnType.number(),
    ),
    PlutoColumn(
      title: '姓名',
      field: 'name',
      type: PlutoColumnType.text(),
    ),
    PlutoColumn(
      title: '邮箱',
      field: 'email',
      type: PlutoColumnType.text(),
    ),
  ];

  // 从API拉取数据并转换为Pluto行格式
  Future<void> fetchData() async {
    isLoading = true;
    errorMessage = null;
    notifyListeners();

    try {
      final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
      if (response.statusCode == 200) {
        final List<dynamic> jsonList = json.decode(response.body);
        final List<User> users = jsonList.map((json) => User.fromJson(json)).toList();
        // 转换为PlutoRow列表
        rows = users.map((user) {
          return PlutoRow(
            cells: {
              'id': PlutoCell(value: user.id),
              'name': PlutoCell(value: user.name),
              'email': PlutoCell(value: user.email),
            },
          );
        }).toList();
      } else {
        errorMessage = '请求失败,状态码:${response.statusCode}';
      }
    } catch (e) {
      errorMessage = '网络错误:${e.toString()}';
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}

步骤3:UI层绑定控制器并渲染

在页面中初始化控制器,通过Provider监听状态变化:

import 'package:flutter/material.dart';
import 'package:pluto_grid/pluto_grid.dart';
import 'package:provider/provider.dart';

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

  @override
  State<PlutoGridDemoPage> createState() => _PlutoGridDemoPageState();
}

class _PlutoGridDemoPageState extends State<PlutoGridDemoPage> {
  late final CustomPlutoGridController _gridController;

  @override
  void initState() {
    super.initState();
    _gridController = CustomPlutoGridController();
    // 页面加载时自动请求数据
    _gridController.fetchData();
  }

  @override
  void dispose() {
    _gridController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('PlutoGrid自定义控制器示例')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: ChangeNotifierProvider.value(
          value: _gridController,
          child: Consumer<CustomPlutoGridController>(
            builder: (context, controller, child) {
              // 加载状态
              if (controller.isLoading) {
                return const Center(child: CircularProgressIndicator());
              }
              // 错误状态
              if (controller.errorMessage != null) {
                return Center(child: Text(controller.errorMessage!, style: const TextStyle(color: Colors.red)));
              }
              // 渲染Grid
              return PlutoGrid(
                columns: controller.columns,
                rows: controller.rows,
                onLoaded: (PlutoGridOnLoadedEvent event) {
                  // 可选:启用列筛选
                  event.stateManager.setShowColumnFilter(true);
                },
              );
            },
          ),
        ),
      ),
    );
  }
}

关键优势说明

  • 状态解耦:所有数据逻辑集中在控制器,UI层无需处理复杂的状态判断,只响应控制器发出的状态变化。
  • 代码复用:控制器可在多个页面复用,避免重复编写API请求和数据转换代码。
  • 易扩展:后续新增行编辑、删除、批量操作等功能,直接在控制器中添加方法即可,UI层调用对应方法即可触发状态更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:47:34