我正在为 PaginatoredDataTable 编写代码,但是当我尝试使用 showDialog() 时我迷失了方向。我想要的是当用户按下数据表中的一行时,会出现一个对话框,其中包含该行包含的信息。我遇到的问题是对话框的上下文,因为它需要上下文,而 DataRow 类本身没有上下文。
为了识别已选择一行,您必须在 DataRow 类中使用 onSelectChanged()。在这里,我尝试调用该对话框,但我必须使用全局导航键。
class CalendarResultsDataSource extends DataTableSource {
final List<CalendarResult> _calendarResults;
CalendarResultsDataSource(this._calendarResults);
@override
DataRow getRow(int index) {
assert(index >= 0);
if (index >= _calendarResults.length) return null;
final CalendarResult calendarResult = _calendarResults[index];
return DataRow.byIndex(
index: index,
selected: calendarResult.selected,
onSelectChanged: (bool value) {
print(value);
print(calendarResult.agency);
Dialogs.showAuditInfo(
navigatorKey.currentState.overlay.context, calendarResult); //<-- this feels hacky
},
cells: <DataCell>[
DataCell(Container(
height: double.infinity,
width: double.infinity,
color: index.isEven
? ColorDefs.colorAlternatingDark
: ColorDefs.colorDarkBackground,
child: Padding(
padding: const EdgeInsets.fromLTRB(6.0, 4.0, 4.0, 4.0),
child: Center(
child: Text('${calendarResult.getDateFormatted()}',
style: ColorDefs.textBodyWhite15)),
))), etc. etc.
]);
Run Code Online (Sandbox Code Playgroud)
在 dataRow 类中。
因此,我在 main() 中创建了一个导航键,如下所示:
final navigatorKey = GlobalKey<NavigatorState>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
home: Scaffold(body: AwesomeAppCodeHere())
);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我在 onSelectChanged() 方法中引用该键,如下所示:
showDialog<void>(
context: navigatorKey.currentState.overlay.context,
builder: (BuildContext context) {
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return DialogInnards();
},
),
);
},
);
Run Code Online (Sandbox Code Playgroud)
但是,感觉很hacky。我能想到的唯一其他解决方案是将上下文从 PaginatoredDataTable 小部件传递到 DataRow 类,但随后我必须直接修改 flutter DataRow 小部件。
那么,在没有公开上下文的情况下获取类中上下文的最佳方法是什么?
我确实看到了“get”包:可能有用... https://pub.dev/packages/get但这对于简单的东西来说不是矫枉过正吗?(但只是逃避我?)
小智 1
我正在处理同样的事情,并且找到了解决方法。\n您可以在 DataTableSource 实现类中声明 BuildContext 属性。
\n class EventData extends DataTableSource {\n final BuildContext context;\n EventData({required this.context});\n final List<Map<String, dynamic>> _data = List.generate(\n 200,\n (index) => {\n "price": Random().nextInt(1000),\n });\n \n @override\n DataRow? getRow(int index) {\n return DataRow(cells: [\n DataCell(Center(\n // We can know use the context in this method.\n child: Text("${_data[index][\'price\']} \xe2\x82\xac",\n style: Theme.of(context)\n .textTheme\n .headline6!\n .copyWith(fontWeight: FontWeight.bold)),\n )),\n ]);\n }\n \n @override\n bool get isRowCountApproximate => false;\n \n @override\n int get rowCount => _data.length;\n \n @override\n int get selectedRowCount => 0;\n }\nRun Code Online (Sandbox Code Playgroud)\n此属性必须由您的 UI 提供,现在可以在 DataTableSource 类的方法中使用。
\nclass PaginatedExample extends StatelessWidget {\n const PaginatedExample({super.key});\n\n @override\n Widget build(BuildContext context) {\n return PaginatedDataTable(\n source: EventData(context: context), //The context can be provided here.\n columns: const [\n DataColumn(label: Text(\'Price\')),\n ],\n );\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n此解决方案的缺点是,EventData 类将在每次 UI 重建时重新实例化。
\n| 归档时间: |
|
| 查看次数: |
1199 次 |
| 最近记录: |