如何使用PaginatedDataTable正确实现对列,字段和行的单击事件

时间:2018-11-26 13:16:20

标签: dart flutter

我不熟悉飞镖和飞镖,所以这是我的第一个应用程序(是!!!)

通常,我正在尝试创建一个包含两行静态数据的表。因为我是初学者,所以我决定开始使用:)

为此,我使用了PaginatedDataTable组件,并创建了一个扩展DataTableSource到表的数据源的类。

每页的默认行设置为10,所以即使当我有两行数据时它也显示2行和8空行,这是否是默认行为?可能不是,我想念一些东西:)

因此,当我单击一个空行时,我得到一个例外,即onTap没有在该行上实现。

为了使我的问题更清楚,这是我的代码:

这是我的Widget函数,它返回PaginatedDataTable组件

Widget searchPageTable()  {
  int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;
  final List<DataColumn> _columns = new List<DataColumn>();
  _columns.add(new DataColumn(label: Text("col1"),onSort: onSort));
  _columns.add(new DataColumn(label: Text("col2"),onSort: onSort));
  _columns.add(new DataColumn(label: Text("col3"),onSort: onSort));
  return new PaginatedDataTable(header: Text("header"),
      columns: _columns,
      rowsPerPage: _rowsPerPage,
    source: new MyDataSource(),
  );
}

所以在这里的列中,我添加了onSort()函数(现在是一个空函数),但是我知道单击列标题并正确实现该函数即可。继续前进。

我的数据源是使用以下代码实现的;

class MyDataSource extends DataTableSource {

  cellTapped() {

  }

  @override
  DataRow getRow(int index) {
    if (index == 0) {
      final List<DataCell> row = new List<DataCell>();
      row.add(new DataCell(Text("col1txt"),onTap: cellTapped));
      row.add(new DataCell(Text("col2txt"),onTap: cellTapped));
      row.add(new DataCell(Text("col3txt"),onTap: cellTapped));
      return new DataRow(cells: row);
    } else if (index == 1) {
      final List<DataCell> row = new List<DataCell>();
      row.add(new DataCell(Text("col1txt2"),onTap: cellTapped));
      row.add(new DataCell(Text("col2txt2"),onTap: cellTapped));
      row.add(new DataCell(Text("col3txt2"),onTap: cellTapped));
      return new DataRow(cells: row);
    } else {
      return null;
    }
  }

  @override
  int get selectedRowCount {
    return 0;
  }

  @override
  bool get isRowCountApproximate {
    return false;
  }

  @override
  int get rowCount {
    return 2;
  }
}

因此,在这里我为每一行创建一个DataRow,在其中为每一列创建一个DataCell,并为每个DataCell实现一个onTap。但是,如果我想更改每一行而不是特定列的onTap,该怎么办?

每当我单击一个空行时,都会出现以下异常:

flutter: ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown while handling a gesture:
flutter: The method 'call' was called on null.
flutter: Receiver: null
flutter: Tried calling: call(true)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
flutter: #1      DataTable.build.<anonymous closure> (package:flutter/src/material/data_table.dart:586:38)
flutter: #2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:507:14)
flutter: #3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:562:30)
flutter: #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
flutter: #5      TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:242:9)
flutter: #6      TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:175:7)
flutter: #7      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:315:9)
flutter: #8      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12)
flutter: #9      PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11)
flutter: #10     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:180:19)
flutter: #11     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:158:22)
flutter: #12     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:138:7)
flutter: #13     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:101:7)
flutter: #14     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:85:7)
flutter: #15     _invoke1 (dart:ui/hooks.dart:168:13)
flutter: #16     _dispatchPointerDataPacket (dart:ui/hooks.dart:122:5)
flutter:
flutter: Handler: onTap
flutter: Recognizer:
flutter:   TapGestureRecognizer#a6733(debugOwner: GestureDetector, state: possible, won arena, finalPosition:
flutter:   Offset(209.0, 375.5), sent tap down)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════

通常,我只想忽略空白行上的点击事件。如何实现呢?

任何有关此问题的信息将不胜感激。

谢谢:)

1 个答案:

答案 0 :(得分:1)

您的第一个问题:“每页的默认行设置为10,因此即使我有两行数据,它也显示2行和8空行,这是否是默认行为?可能不是,我也没有东西:)“

是的,这是预期的行为,因为它将创建每页行属性中指定的行数。

您的第二个问题:“每当我单击空白行时,都会出现以下异常:...”

这是因为在您的getRow函数中,当null时它返回index > 1,因此也期望出现异常。实际上,您不想对数据源进行硬编码并不想根据数据源有多少行按比例设置每页行数。例如,如果您知道数据源将从100行开始,则可以将每个页面设置为10或20行。理想情况下,应根据数据源更新动态构建页面,从而避免页面中有空行。但是,此异常不会使您的应用程序崩溃,并且如果您想简化操作,则可以在某种程度上忽略该异常。

关于处理每行onTap的最后一个问题。

我假设您要对选定的行执行某些操作,例如,您可以根据是否选择了任何行来启用/禁用某些按钮。请注意,actions上有一个List<Widget>属性(类型为PaginatedDataTable),您可以放置​​一些所需的按钮或其他小部件。我这样做的方法是通过将事件处理程序(例如onRowSelected只是一个不带参数且不返回任何内容的函数)传入MyDataSource构造函数中,并在其中的onSelectedChanged处理函数上调用它getRow函数,您将在其中返回一个DataRow。这是我为您提供具体想法的一个示例:

class OrderSource extends DataTableSource {
  int _selectedCount = 0;
  final List<Order> _orders;
  final Function onRowSelected;
  OrderSource(this._orders, this.onRowSelected);

  @override
  DataRow getRow(int index) {
    assert(index >= 0);
    if (index >= _orders.length) return null;
    final Order order = _orders[index];
    return DataRow.byIndex(
        index: index,
        selected: order.selected,
        onSelectChanged: (bool value) {
          if (order.selected != value) {
            _selectedCount += value ? 1 : -1;
            assert(_selectedCount >= 0);
            order.selected = value;
            notifyListeners();
            onRowSelected();
            //print('selected rows: $selectedRowCount');
          }
        },
        cells: <DataCell>[
          DataCell(Text('${order.orderID}')),
          DataCell(Text('${order.side}')),
          ...),
        ]);
  }
}

希望这会有所帮助。