简体   繁体   English

Flutter PaginatedDataTable rowsPerPage

[英]Flutter PaginatedDataTable rowsPerPage

Can flutter PaginatedDataTable rowsPerPage be set to a number not divisible by 10?能扑PaginatedDataTable rowsPerPage被设置为一个数字不是10整除?

UPDATE更新

Data used by the FutureBuilder is fetched from a local server. FutureBuilder 使用的数据是从本地服务器获取的。 At first, the list contains 3 items which results into empty DataRows being created.起初,该列表包含 3 个项目,这会导致创建空的 DataRow。

My Problem我的问题

  1. I don't want the empty DataRows to be created我不希望创建空的 DataRows

What I've Tried我试过的

  1. Setting the rowsPerPage count to the length of the list IF the list-length is less than the defaultRowsPerPage ELSE set it (rowsPerPage) to defaultRowsPerPage.如果列表长度小于 defaultRowsPerPage,则将 rowsPerPage 计数设置为列表的长度,否则将其 (rowsPerPage) 设置为 defaultRowsPerPage。

SAMPLE CODE示例代码

import 'package:flutter/material.dart';
import 'package:nvip/constants.dart';
import 'package:nvip/data_repo/network/centers_repo.dart';
import 'package:nvip/data_repo/tables/data_source_centers.dart';
import 'package:nvip/models/vaccination_center.dart';

class VaccinationCentersTableScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) => _CentersScreenBody();
}

class _CentersScreenBody extends StatefulWidget {
  @override
  __CentersScreenBodyState createState() => __CentersScreenBodyState();
}

class __CentersScreenBodyState extends State<_CentersScreenBody> {
  int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage; // This one works
  int _columnIndex = 1;
  bool _isSortAscending = true;
  Future<List<VaccineCenter>> _centers;
  CentersTableDataSource _tableDataSource;
  var _scaffoldKey = GlobalKey<ScaffoldState>();

  void _sort<T>(Comparable<T> getField(VaccineCenter c), int columnIndex,
      bool isSortAscending) {
    _tableDataSource?.sort(getField, isSortAscending);
    setState(() {
      _columnIndex = columnIndex;
      _isSortAscending = isSortAscending;
    });
  }

  @override
  void initState() {
    super.initState();
    _centers = VaccineCentersDataRepo().getCenters();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        Navigator.pushReplacementNamed(context, Routes.keyHome);
      },
      child: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: Text("Vaccination Centers"),
          centerTitle: true,
          leading: IconButton(
            icon: Icon(Constants.backIcon),
            onPressed: () {
              Navigator.pushReplacementNamed(context, Routes.keyHome);
            },
          ),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.add),
              tooltip: "Add vaccination center",
              onPressed: () {
                Navigator.pushReplacementNamed(context, Routes.keyPovAdd);
              },
            )
          ],
        ),
        body: FutureBuilder<List<VaccineCenter>>(
          future: _centers,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Constants.showHasNoDataWidget(
                context,
                "No vaccination center(s) / place(s) of vaccinations found. "
                    "Press the (+) sign to add a new record.",
              );
            } else {
              if (snapshot.hasData) {
                var centerList = snapshot.data;
                var centersCount = centerList.length;
                var defaultRowsPerPage = PaginatedDataTable.defaultRowsPerPage;
                _rowsPerPage = centersCount < defaultRowsPerPage
                    ? centersCount
                    : defaultRowsPerPage;
                _tableDataSource = CentersTableDataSource(centerList);
                return SingleChildScrollView(
                  child: PaginatedDataTable(
                    header: Text("Places of Vaccination"),
                    rowsPerPage: _rowsPerPage,
                    onRowsPerPageChanged: (rowCount) {
                      setState(() {
                        _rowsPerPage = rowCount;
                      });
                    },
                    sortColumnIndex: _columnIndex,
                    sortAscending: _isSortAscending,
                    onSelectAll: (isAllChecked) =>
                        _tableDataSource?.selectAll(isAllChecked),
                    actions: <Widget>[
                      IconButton(
                        icon: Icon(Icons.add),
                        tooltip: "Add vaccination center",
                        onPressed: () {
                          Navigator.pushReplacementNamed(
                              context, Routes.keyPovAdd);
                        },
                      ),
                      IconButton(
                        icon: Icon(Icons.delete_forever),
                        tooltip: "Delete vaccination center(s).",
                        onPressed: () {
                          Constants.showSnackBar(
                              _scaffoldKey, "Delete button clicked");
                        },
                      )
                    ],
                    columns: <DataColumn>[
                      DataColumn(
                        label: Text("No."),
                        numeric: true,
                        onSort: (ci, isSortAscending) => _sort<num>(
                            (c) => centerList.indexOf(c), ci, isSortAscending),
                      ),
                      DataColumn(
                        label: Text("Name"),
                        onSort: (ci, isSortAscending) =>
                            _sort<String>((c) => c.name, ci, isSortAscending),
                      ),
                    ],
                    source: _tableDataSource,
                  ),
                );
              }
            }

            return Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }
}

ERROR LOG错误日志

I/flutter ( 8474): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 8474): The following assertion was thrown building FutureBuilder<List<VaccineCenter>>(dirty, state:
I/flutter ( 8474): _FutureBuilderState<List<VaccineCenter>>#92379):
I/flutter ( 8474): 'package:flutter/src/material/paginated_data_table.dart': Failed assertion: line 87 pos 19:
I/flutter ( 8474): 'availableRowsPerPage != null && availableRowsPerPage.contains(rowsPerPage)': is not true.
I/flutter ( 8474): 
I/flutter ( 8474): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter ( 8474): more information in this error message to help you determine and fix the underlying cause.
I/flutter ( 8474): In either case, please report this assertion by filing a bug on GitHub:
I/flutter ( 8474):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 8474): 
I/flutter ( 8474): When the exception was thrown, this was the stack:
I/flutter ( 8474): #2      new PaginatedDataTable.<anonymous closure> (package:flutter/src/material/paginated_data_table.dart:87:19)
I/flutter ( 8474): #3      new PaginatedDataTable (package:flutter/src/material/paginated_data_table.dart:89:9)
I/flutter ( 8474): #4      __CentersScreenBodyState.build.<anonymous closure> (package:nvip/scenes/vaccination_centers/screen_center_table.dart:86:26)
I/flutter ( 8474): #5      _FutureBuilderState.build (package:flutter/src/widgets/async.dart)
I/flutter ( 8474): #6      StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter ( 8474): #7      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter ( 8474): #8      Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter ( 8474): #9      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
I/flutter ( 8474): #10     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20)
I/flutter ( 8474): #11     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter ( 8474): #12     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter ( 8474): #13     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter ( 8474): #14     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter ( 8474): #15     _invoke (dart:ui/hooks.dart:154:13)
I/flutter ( 8474): #16     _drawFrame (dart:ui/hooks.dart:143:3)
I/flutter ( 8474): (elided 2 frames from class _AssertionError)
I/flutter ( 8474): ════════════════════════════════════════════════════════════════════════════════════════════════════

UPDATE 2更新 2

My DataTableSource我的数据表源

import 'package:flutter/material.dart';
import 'package:nvip/models/vaccination_center.dart';

class CentersTableDataSource extends DataTableSource {
  final List<VaccineCenter> _centers;
  int _rowsSelectedCount = 0;

  CentersTableDataSource(this._centers);

  @override
  DataRow getRow(int index) {
    assert(index >= 0);
    if (index >= _centers.length) return null;
    final VaccineCenter center = _centers[index];
    return DataRow.byIndex(
      index: index,
      selected: center.isSelected,
      onSelectChanged: (selected) {
        if (center.isSelected != selected) {
          _rowsSelectedCount += selected ? 1 : -1;
          center.isSelected = selected;
          notifyListeners();
        }
      },
      cells: <DataCell>[
        DataCell(Text("${index + 1}")),
        DataCell(Text(center.name)),
      ],
    );
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => _centers.length;

  @override
  int get selectedRowCount => _rowsSelectedCount;

  void sort<T extends Object>(
      Comparable<T> getField(VaccineCenter d), bool isAscending) {
    _centers.sort((a, b) {
      if (isAscending) {
        final VaccineCenter c = a;
        a = b;
        b = c;
      }

      final Comparable<T> aValue = getField(a);
      final Comparable<T> bValue = getField(b);
      return Comparable.compare(aValue, bValue);
    });
    notifyListeners();
  }

  void selectAll(bool isAllChecked) {
    _centers.forEach((center) => center.isSelected = isAllChecked);
    _rowsSelectedCount = isAllChecked ? _centers.length : 0;
    notifyListeners();
  }
}
  import 'package:flutter/material.dart';

    class DemoTable extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return _DemoTableBody();
      }
    }

    class _DemoTableBody extends StatefulWidget {
      @override
      __DemoTableBodyState createState() => __DemoTableBodyState();
    }

    class __DemoTableBodyState extends State<_DemoTableBody> {

      int _rowsPerPage = PaginatedDataTable.defaultRowsPerPage;

      // A Variable to hold the length of table based on the condition of comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage

      int _rowsPerPage1 = PaginatedDataTable.defaultRowsPerPage;

      @override
      Widget build(BuildContext context) {

      //Obtain the data to be displayed from the Derived DataTableSource

        var dts = DTS(); 

        // dts.rowcount provides the actual data length, ForInstance, If we have 7 data stored in the DataTableSource Object, then we will get 12 as dts.rowCount

       var tableItemsCount = dts.rowCount; 

        // PaginatedDataTable.defaultRowsPerPage provides value as 10

        var defaultRowsPerPage = PaginatedDataTable.defaultRowsPerPage;

        // We are checking whether tablesItemCount is less than the defaultRowsPerPage which means we are actually checking the length of the data in DataTableSource with default PaginatedDataTable.defaultRowsPerPage i.e, 10

        var isRowCountLessDefaultRowsPerPage = tableItemsCount < defaultRowsPerPage;

        // Assigning rowsPerPage as 10 or acutal length of our data in stored in the DataTableSource Object

        _rowsPerPage =
            isRowCountLessDefaultRowsPerPage ? tableItemsCount : defaultRowsPerPage;
        return Scaffold(
          appBar: AppBar(
            title: Text("Demo Paginated Table"),
          ),
          body: SingleChildScrollView(
            child: PaginatedDataTable(
              header: Text('data with 7 rows per page'),
              // comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage and then assigning it to _rowPerPage1 variable which then set using the setsState()
              onRowsPerPageChanged: isRowCountLessDefaultRowsPerPage // The source of problem!
                  ? null
                  : (rowCount) {
                      setState(() {
                        _rowsPerPage1 = rowCount;
                      });
                    },
              columns: <DataColumn>[
                DataColumn(label: Text('row')),
                DataColumn(label: Text('name')),
              ],
              source: dts,
              //Set Value for rowsPerPage based on comparing the actual data length with the PaginatedDataTable.defaultRowsPerPage 
              rowsPerPage:
                  isRowCountLessDefaultRowsPerPage ? _rowsPerPage : _rowsPerPage1,
            ),
          ),
        );
      }
    }

    class DTS extends DataTableSource {
      @override
      DataRow getRow(int index) {
        return DataRow.byIndex(
          index: index,
          cells: [
            DataCell(Text('row #$index')),
            DataCell(Text('name #$index')),
          ],
        );
      }

      @override
      int get rowCount => 9; // Manipulate this to which ever value you wish

      @override
      bool get isRowCountApproximate => false;

      @override
      int get selectedRowCount => 0;
    }

This error is caused by the values provided by flutter.这个错误是由flutter提供的值引起的。 rowsPerPage can only be 10, 20, 50 and 100. rowsPerPage 只能是 10、20、50 和 100。

snapshot source PaginatedDataTable快照源分页数据表

This is specified in the source PaginatedDataTable .这是在源PaginatedDataTable 中指定的。

I'm leaving this for the next guy since I just battled this recently.我要把这个留给下一个家伙,因为我最近刚和这个战斗过。

Right now, it seems like PaginatedDataTable has a couple of bugs in it... this is one of them.现在,PaginatedDataTable 似乎有几个错误……这是其中之一。 If the number of data elements doesn't exactly equal the selected number of rows per page, the PaginatedDataTable widget puts in 'filler rows'如果数据元素的数量不完全等于每页选定的行数,PaginatedDataTable 小部件将放入“填充行”

Until this is fixed, I'd recommend taking the flutter PaginatedDataTable widget in the file paginated_data_table.dart and putting it in your project in order to customize it.在修复此问题之前,我建议在文件 paginated_data_table.dart 中使用 flutter PaginatedDataTable 小部件并将其放入您的项目中以对其进行自定义。 (you'll have to replace all of the dependencies that aren't found with a simple import 'package:flutter/material.dart'; (您必须用简单的import 'package:flutter/material.dart';替换所有未找到的依赖项import 'package:flutter/material.dart';

In order to limit the number of seen rows, add the lines with // <--- below in the _getRows method seen below:为了限制看到的行数,在下面看到的 _getRows 方法中添加带有 // <--- 下面的行:

  List<DataRow> _getRows(int firstRowIndex, int rowsPerPage) {
    final List<DataRow> result = <DataRow>[];
    final int nextPageFirstRowIndex = firstRowIndex + rowsPerPage;
    bool haveProgressIndicator = false;
    for (int index = firstRowIndex; index < nextPageFirstRowIndex; index += 1) {
      if (index < _rowCount) {  // <---
        // This stops "overflow" rows from appearing on the last page.
        DataRow row;
        if (index < _rowCount || _rowCountApproximate) {
          row = _rows.putIfAbsent(index, () => widget.source.getRow(index));
          if (row == null && !haveProgressIndicator) {
            row ??= _getProgressIndicatorRowFor(index);
            haveProgressIndicator = true;
          }
        }
        row ??= _getBlankRowFor(index);
        result.add(row);
      }                      // <---
    }
    return result;
  }

Additionally, the page count will now be off, so you'll have to change this section below in order to add the ternary operator to change the final count:此外,页面计数现在将关闭,因此您必须更改下面的此部分以添加三元运算符以更改最终计数:

Text(
     localizations.pageRowsInfoTitle(
     _firstRowIndex + 1,
     (_firstRowIndex + widget.rowsPerPage <= _rowCount)?_firstRowIndex + widget.rowsPerPage:_rowCount,
     _rowCount,
     _rowCountApproximate,
    ),
  ),

rowsPerPage and availableRowsPerPage need to be defined together. rowsPerPageavailableRowsPerPage需要一起定义。 For example:例如:

_rowsPerPage = 5;

recalculate _rowsPerPage in build method:在构建方法中重新计算_rowsPerPage

    @override
      Widget build(BuildContext context) {
        _rowsPerPage = widget.items.length > 5 ? 5 : widget.items.length;
        return _buildCollectivePanel();
      }

then add rowsPerPage , availableRowsPerPage to the PaginatedDataTable in _buildCollectivePanel()然后添加rowsPerPageavailableRowsPerPagePaginatedDataTable_buildCollectivePanel()

PaginatedDataTable(
                header: Text("dataTableHeader"),
                rowsPerPage: _rowsPerPage,
                availableRowsPerPage: <int>[_rowsPerPage, _rowsPerPage * 2, _rowsPerPage * 5, _rowsPerPage * 10],......

Let's say you have some method that fetches data from a remote server or locally and return a list of objects like this :假设您有一些方法可以从远程服务器或本地获取数据并返回如下对象列表:

List<Map<String, String>> fetchedDataObj = [
  {
    "name": "Rami",
    "email": "dummyemail01@gmail.com"
  },
  {
    "name": "Kara",
    "email": "dummyemail02@gmail.com"
  },
  {
    "name": "Lina",
    "email": "dummyemail03@almakana.com"
  }
];

in PaginatedDataTable widget set :PaginatedDataTable小部件集中:

rowsPerPage: fetchedDataObj.length,

and

onRowsPerPageChanged: (fetchedDataObj.length < PaginatedDataTable.defaultRowsPerPage) ? null : (r) {
          // setState(() {
          //   _rowsPerPage = r;
          // });
        },
      ),

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

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

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