list_controller 0.1.0 copy "list_controller: ^0.1.0" to clipboard
list_controller: ^0.1.0 copied to clipboard

Tools for creating list controllers. Supports infinite scroll, pagination, lazy loading, sorting, filtering, synchronization, huge lists, etc. Architecture and widgets agnostic.

example/lib/main.dart

import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:list_controller/list_controller.dart';

class ListQuery extends Equatable {
  const ListQuery({this.weightGt = 0});

  final int weightGt;

  @override
  List<Object?> get props => [weightGt];
}

typedef ListStateExample = ListState<int, ListQuery>;

class LoadResult {
  const LoadResult({required this.records, required this.isFinalPage});

  final List<int> records;
  final bool isFinalPage;
}

void main() {
  runApp(const MaterialApp(
    title: 'List Controller Example',
    home: MyHomePage(),
  ));
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key}) : super();

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with
        ListCore<int>,
        RecordsLoader<int, ListQuery, LoadResult>,
        KeysetPagination<int, ListQuery, LoadResult> {
  ListStateExample state = const ListStateExample(query: ListQuery());

  @override
  void initState() {
    loadRecords(state.query);
    super.initState();
  }

  @override
  void dispose() {
    closeList();
    super.dispose();
  }

  // RecordsLoader section:

  @override
  void onRecordsLoadStart(
          {required ListQuery query, required LoadingKey loadingKey}) =>
      setState(() {
        state = state.copyWith(stage: ListStage.loading());
      });

  @override
  Future<LoadResult> performLoadQuery(
      {required ListQuery query, required LoadingKey loadingKey}) async {
    await Future.delayed(const Duration(milliseconds: 1500));
    return LoadResult(
      records: List<int>.generate(20, (i) => query.weightGt + i + 1),
      isFinalPage: query.weightGt >= 80,
    );
  }

  @override
  void putLoadResultToState(
          {required ListQuery query,
          required LoadResult loadResult,
          required LoadingKey loadingKey}) =>
      setState(() {
        state = state.copyWith(
          records: [
            ...state.records,
            ...loadResult.records,
          ],
          stage:
              loadResult.isFinalPage ? ListStage.complete() : ListStage.idle(),
        );
      });

  // KeysetPagination section:

  @override
  ListStage getListStage(LoadingKey loadingKey) => state.stage;

  @override
  ListQuery buildNextPageQuery(LoadingKey loadingKey) =>
      ListQuery(weightGt: state.records.last);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('List Controller Example'),
      ),
      body: Stack(
        children: [
          ListView.builder(
            itemCount: state.records.length,
            itemBuilder: (context, index) {
              const recordsLoadThreshold = 1;
              if (index >= state.records.length - recordsLoadThreshold) {
                WidgetsBinding.instance.addPostFrameCallback((_) {
                  loadNextPage();
                });
              }
              return ListTile(title: Text(state.records[index].toString()));
            },
          ),
          if (state.isLoading) const Center(child: CircularProgressIndicator()),
        ],
      ),
    );
  }
}
8
likes
140
pub points
66%
popularity

Publisher

verified publisherastonio.com

Tools for creating list controllers. Supports infinite scroll, pagination, lazy loading, sorting, filtering, synchronization, huge lists, etc. Architecture and widgets agnostic.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

async, collection, meta, rxdart

More

Packages that depend on list_controller