简体   繁体   English

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

[英]how to properly implement click events on columns, fields and rows with PaginatedDataTable

I'm new to flutter and dart, so this is my first app (yay!!!) 我不熟悉飞镖和飞镖,所以这是我的第一个应用程序(是!!!)

in general I'm trying to create a table with two static rows of data. 通常,我试图用两个静态数据行创建一个表。 since I'm a beginner that what I've decided to start and play with :) 因为我是一个初学者,所以我决定从这里开始玩:)

I use the PaginatedDataTable component for that, and I create a class that extends DataTableSource for the data source of the table. 为此,我使用了PaginatedDataTable组件,并且创建了一个扩展DataTableSource作为表数据源的类。

the default rows per page is set to 10, so even when I have two rows of data it shows 2 rows and 8 empty rows, is that that the default behaviour ? 每页的默认行设置为10,所以即使当我有两行数据时它也显示2行和8空行,这是否是默认行为? probably not and I'm missing something :) 可能不是,我想念一些东西:)

so when I click on an empty row I get an exception that onTap isn't being implemented on that row. 因此,当我单击一个空行时,我得到一个例外,即该行未实现onTap

to make my question clearer this is my code: 为了使我的问题更清楚,这是我的代码:

this is my Widget function that returns the PaginatedDataTable component 这是我的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(),
  );
}

so here in the columns I added the onSort() function (for now an empty function) but I know that I can catch when clicking on column titles and implement that properly. 所以在这里我在列中添加了onSort()函数(现在是一个空函数),但是我知道单击列标题并正确实现时可以捕获。 moving on.. 继续..

my data source is implement with the following code; 我的数据源是用以下代码实现的;

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;
  }
}

so here for each row I create a DataRow and in it for each column a DataCell and I implement an onTap for each DataCell. 所以在这里,我为每一行创建一个DataRow并在其中为每一列创建一个DataCell并为每个DataCell实现一个onTap but what if I wanna change the onTap for each row and not for specific columns, how an I do that ? 但是,如果我想更改每一行而不是特定列的onTap怎么办,我该怎么做?

and whenever I click on an empty row, I get the following exception: 每当我单击空白行时,都会收到以下异常:

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: ════════════════════════════════════════════════════════════════════════════════════════════════════

in general here I just want to ignore click events on empty row. 总的来说,我只想忽略空白行上的点击事件。 how to implement that ? 如何实施?

any information regarding this issue would be appreciated. 有关此问题的任何信息将不胜感激。

thanks :) 谢谢 :)

You first question: "the default rows per page is set to 10, so even when I have two rows of data it shows 2 rows and 8 empty rows, is that that the default behaviour ? probably not and I'm missing something :)" 您的第一个问题是:“每页的默认行设置为10,因此即使我有两行数据,它也显示2行和8空行,这是否是默认行为?可能不是,并且我缺少了一些东西:) “

Yes, this is the expected behaviour because it will create the number of rows specified in rows per page property. 是的,这是预期的行为,因为它将创建在每页行属性中指定的行数。

Your 2nd question: "whenever I click on an empty row, I get the following exception:..." 您的第二个问题:“每当我单击空白行时,都会出现以下异常:...”

This is because in your getRow function it returns null when index > 1 so the exception is also expected. 这是因为在您的getRow函数中,当index > 1时,它将返回null ,因此也应预期该异常。 Practically, you don't want to hard-code your data source and set rows per page proportionally based on how many rows your data source has. 实际上,您不想对数据源进行硬编码并不想根据数据源有多少行按比例设置每页行数。 For instance, if you know your data source will start with 100 rows, then you can either set each page having 10 or 20 rows. 例如,如果您知道数据源将从100行开始,则可以将每个页面设置为10或20行。 You should ideally avoid having empty rows in the page by dynamically building the page based on your data source update. 理想情况下,应根据数据源更新动态构建页面,从而避免页面中有空行。 But this exception is not going to crash your app and to some extent can be ignored if you want to simplify things. 但是,此异常不会使您的应用程序崩溃,并且如果您想简化操作,则可以在某种程度上忽略该异常。

Your final question about handling onTap of each row. 关于处理每一行的onTap的最后一个问题。

I am assuming you want to execute some actions to the selected row(s), for instance, you can enable/disable some buttons based on whether there is any row being selected. 我假设您要对选定的行执行某些操作,例如,您可以根据是否有任何行被选中来启用/禁用某些按钮。 Note that there is an actions property (of type List<Widget> ) on the PaginatedDataTable and you can put some buttons or other widgets you want. 注意,在PaginatedDataTable上有一个actions属性(类型为List<Widget> ),您可以放置​​一些按钮或所需的其他小部件。 The way I did this is via passing in a event handler (such as onRowSelected which is simply a function taking no argument and returning nothing) into MyDataSource constructor and call it on onSelectedChanged handler within getRow function where you return a DataRow . 我这样做的方法是通过将事件处理程序(例如onRowSelected ,它只是一个不带参数且不返回任何内容的函数)传入MyDataSource构造函数,并在getRow函数中的onSelectedChanged处理函数上调用它,并在其中返回DataRow This is an example of what I did to give you a specific idea: 这是我为您提供具体想法的一个示例:

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}')),
          ...),
        ]);
  }
}

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM