initializeRowsAsync static method

Future<List<PlutoRow>> initializeRowsAsync(
  1. List<PlutoColumn> refColumns,
  2. List<PlutoRow> refRows, {
  3. bool forceApplySortIdx = true,
  4. bool increase = true,
  5. int start = 0,
  6. int chunkSize = 100,
  7. Duration duration = const Duration(milliseconds: 1),
})

An asynchronous version of PlutoGridStateManager.initializeRows.

PlutoGridStateManager.initializeRowsAsync repeats Timer every duration, Process the setting of refRows by the size of chunkSize. Isolate is a good way to handle CPU heavy work, but The condition that List

forceApplySortIdx determines whether to force PlutoRow.sortIdx to be set.

increase and start are valid only when forceApplySortIdx is true.

increase determines whether to increment or decrement when initializing sortIdx. For example, if a row is added before an existing row, the sortIdx value should be set to a negative number than the row being added.

start sets the starting value when initializing sortIdx. For example, if sortIdx is set from 0 to 9 in the previous 10 rows, start is set to 10, which sets the sortIdx of the row added at the end.

chunkSize determines the number of lists processed at one time when setting rows.

duration determines the processing interval when setting rows.

If pagination is set, PlutoGridStateManager.setPage must be called after Future is completed before Rows appear on the screen.

PlutoGridStateManager.initializeRowsAsync(columns, fetchedRows).then((initializedRows) {
  stateManager.refRows.addAll(initializedRows);
  stateManager.setPage(1, notify: false);
  stateManager.notifyListeners();
});

It is created when PlutoGrid is first created, and the state required for the grid is set for List<PlutoRow> rows. PlutoGridStateManager.initializeRows, which operates at this time, works synchronously, and if there are many rows, the UI may freeze when starting the grid.

To prevent UI from freezing when passing many rows to PlutoGrid, you can set rows asynchronously as follows. After passing an empty list when creating PlutoGrid, add rows initialized with initializeRowsAsync as shown below.

PlutoGridStateManager.initializeRowsAsync(
  columns,
  fetchedRows,
).then((value) {
  stateManager.refRows.addAll(FilteredList(initialList: value));
  stateManager.notifyListeners();
});

Implementation

static Future<List<PlutoRow>> initializeRowsAsync(
  List<PlutoColumn> refColumns,
  List<PlutoRow> refRows, {
  bool forceApplySortIdx = true,
  bool increase = true,
  int start = 0,
  int chunkSize = 100,
  Duration duration = const Duration(milliseconds: 1),
}) {
  if (refColumns.isEmpty || refRows.isEmpty) {
    return Future.value(refRows);
  }

  assert(chunkSize > 0);

  final Completer<List<PlutoRow>> completer = Completer();

  SplayTreeMap<int, List<PlutoRow>> splayMapRows = SplayTreeMap();

  final Iterable<List<PlutoRow>> chunks = refRows.slices(chunkSize);

  final chunksLength = chunks.length;

  final List<int> chunksIndexes = List.generate(
    chunksLength,
    (index) => index,
  );

  Timer.periodic(duration, (timer) {
    if (chunksIndexes.isEmpty) {
      return;
    }

    final chunkIndex = chunksIndexes.removeLast();

    final chunk = chunks.elementAt(chunkIndex);

    Future(() {
      return PlutoGridStateManager.initializeRows(
        refColumns,
        chunk,
        forceApplySortIdx: forceApplySortIdx,
        increase: increase,
        start: start + (chunkIndex * chunkSize),
      );
    }).then((value) {
      splayMapRows[chunkIndex] = value;

      if (splayMapRows.length == chunksLength) {
        completer.complete(
          splayMapRows.values.expand((element) => element).toList(),
        );

        timer.cancel();
      }
    });
  });

  return completer.future;
}