PlutoGrid单元格中点击IconButton后如何显示Dialog组件?
错误原因
Dart的类成员初始化器会在构造函数执行之前运行,此时类实例还未完全创建,无法访问_selectDialog这类实例方法(因为实例方法依赖于已初始化的对象实例),所以会抛出The instance member '_selectDialog' can't be accessed in an initializer.错误。
可行解决方案
方案1:使用late延迟初始化列配置
通过late关键字延迟列的初始化时机,直到第一次使用该列时才完成初始化,此时实例已创建完成,可正常访问实例方法。
import 'package:flutter/material.dart'; import 'package:pluto_grid/pluto_grid.dart'; class MyGridPage extends StatefulWidget { const MyGridPage({super.key}); @override State<MyGridPage> createState() => _MyGridPageState(); } class _MyGridPageState extends State<MyGridPage> { // 使用late延迟初始化列 late final PlutoColumn actionColumn = PlutoColumn( title: '操作', field: 'action', renderer: (rendererContext) { return IconButton( icon: const Icon(Icons.edit), // 此时可正常调用实例方法 onPressed: () => _selectDialog(rendererContext.context), ); }, ); void _selectDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('选择弹窗'), content: const Text('这是测试弹窗内容'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( body: PlutoGrid( columns: [actionColumn], rows: List.generate(5, (index) => PlutoRow(cells: { 'action': PlutoCell(value: ''), })), ), ); } }
方案2:在initState中初始化列配置
initState是StatefulWidget实例创建完成后第一个执行的生命周期方法,此时实例已完全初始化,可安全访问实例方法。
import 'package:flutter/material.dart'; import 'package:pluto_grid/pluto_grid.dart'; class MyGridPage extends StatefulWidget { const MyGridPage({super.key}); @override State<MyGridPage> createState() => _MyGridPageState(); } class _MyGridPageState extends State<MyGridPage> { late PlutoColumn actionColumn; @override void initState() { super.initState(); // 在initState中初始化列,此时可访问实例方法 actionColumn = PlutoColumn( title: '操作', field: 'action', renderer: (rendererContext) { return IconButton( icon: const Icon(Icons.edit), onPressed: () => _selectDialog(rendererContext.context), ); }, ); } void _selectDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('选择弹窗'), content: const Text('这是测试弹窗内容'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( body: PlutoGrid( columns: [actionColumn], rows: List.generate(5, (index) => PlutoRow(cells: { 'action': PlutoCell(value: ''), })), ), ); } }
方案3:在StatelessWidget中直接在build方法内初始化列
如果使用StatelessWidget,可将列的初始化逻辑放在build方法内部,此时Widget已完成构建,可正常调用内部方法。
import 'package:flutter/material.dart'; import 'package:pluto_grid/pluto_grid.dart'; class MyGrid extends StatelessWidget { const MyGrid({super.key}); void _selectDialog(BuildContext context) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('选择弹窗'), content: const Text('这是测试弹窗内容'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } @override Widget build(BuildContext context) { // 在build方法内初始化列 final actionColumn = PlutoColumn( title: '操作', field: 'action', renderer: (rendererContext) { return IconButton( icon: const Icon(Icons.edit), onPressed: () => _selectDialog(rendererContext.context), ); }, ); return PlutoGrid( columns: [actionColumn], rows: List.generate(5, (index) => PlutoRow(cells: { 'action': PlutoCell(value: ''), })), ); } }
内容的提问来源于stack exchange,提问作者Olli73
相关产品推荐
相关产品推荐

