如何通过自定义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
相关产品推荐
相关产品推荐

