A Flutter ListView in which items can be grouped into sections.

Overview

Grouped list package for Flutter.

Pub CI

Now with beta support for null safety!

A flutter ListView in which list items can be grouped to sections.

Features

  • Sound null safety support!
  • Easy creation of chat dialog.
  • List Items can be separated in groups.
  • For the groups an individual header can be set.
  • Almost all fields from ListView.builder available.

Getting Started

Add the package to your pubspec.yaml:

 grouped_list: ^4.1.0

In your dart file, import the library:

import 'package:grouped_list/grouped_list.dart';

Instead of using a ListView create a GroupedListView Widget:

 GroupedListView<dynamic, String>(
   elements: _elements,
   groupBy: (element) => element['group'],
   groupSeparatorBuilder: (String groupByValue) => Text(groupByValue),
   itemBuilder: (context, dynamic element) => Text(element['name']),
   itemComparator: (item1, item2) => item1['name'].compareTo(item2['name']), // optional
   useStickyGroupSeparators: true, // optional
   floatingHeader: true, // optional
   order: GroupedListOrder.ASC, // optional
 ),

Parameters:

Name Description Required Default value
elements A list of the data you want to display in the list required -
groupBy Function which maps an element to its grouped value required -
itemBuilder / indexedItemBuilder Function which returns an Widget which defines the item. indexedItemBuilder provides the current index as well. If both are defined indexedItemBuilder is preferred yes, either of them -
groupSeparatorBuilder / groupHeaderBuilder Function which returns an Widget which defines the group headers. While groupSeparatorBuilder gets the groupBy-value as parameter groupHeaderBuilder gets the whole element. If both are defined groupHeaderBuilder is preferred yes, either of them -
useStickyGroupSeparators When set to true the group header of the current visible group will stick on top no false
floatingHeader Whether the sticky group header float over the list or occupy it's own space no false
stickyHeaderBackgroundColor Defines the background color of the sticky header. Will only be used if useStickyGroupSeparators is used no Color(0xffF7F7F7)
separator A Widget which defines a separator between items inside a group no no separator
groupComparator  Can be used to define a custom sorting for the groups. Otherwise the natural sorting order is used no -
itemComparator  Can be used to define a custom sorting for the elements inside each group. Otherwise the natural sorting order is used no -
order  Change to GroupedListOrder.DESC to reverse the group sorting no GroupedListOrder.ASC

Also the fields from ListView.builder can be used.

Highlight - SilverGroupedList

Now supporting a grouped list based on a silver list. Just use SilverGroupedListView instead of GroupedListView. An example can be found under example/lib/example_silver. Note that some options of the GroupedListView are currently not available in SilverGroupedListView.

Highlight - Chat Dialog

Easy creation of chat dialogs. Just set the option reverse to true and order to GroupedListOrder.DESC. A full example can be found in the examples. The list will be scrolled to the end in the initial state and therefore scrolling will be against redeaing direction.

My other packages :

For easy creation of chat-like dialogs:

Check out my other package StickyGroupedList, which is based on the scrollable_positioned_list.

Comments
  • Possible performance issue in 3.0

    Possible performance issue in 3.0

    I tried upgrading form 2.31 to 3.0. After the upgrade the parent widget where I have GroupedListView gets rebuilt every time I scroll the list view. In other words the widget including GroupedListView is rebuilt repeatedly unnecessarily. This makes the list very slow. Issue gets fixed if I revert to 2.3.1. Any ideas what could be wrong?

    Simplified build method where the problem occurs:

      @override
      Widget build(BuildContext context) {
         return ChangeNotifierProvider<ItemsViewModel>.value(
            value: _items,
            child: Consumer<ItemsViewModel>(
                builder: (context, viewModel, _) {
                return GroupedListView(elements: viewModels.items,...);
              }
    ...
    
    opened by kinex 22
  • Order groups by

    Order groups by

    Hi, first of all thank you for creating a great & useful package. I wanted to ask - is there a way to order the groups by a custom (and not alphabetical) order? Thank you!

    opened by xJon 20
  • Implement new sorting options

    Implement new sorting options

    Hi I am looking to sort the elements by the days in the week instead of just ASC and DESC. I tried to edit from the original sort for ASC. These are the edits I have made to the grouped_list.dart file, but the app still remains to retain the original ASC sorting properties. Am I missing a step?

    Screen Shot 2020-05-31 at 23 08 18 PM
    opened by jadenwjh 12
  • RangeError (index): Invalid value: Not in inclusive range 0..14: 16

    RangeError (index): Invalid value: Not in inclusive range 0..14: 16

    class LongListPage extends StatefulWidget {
      @override
      _LongListPageState createState() => _LongListPageState();
    }
    
    class _LongListPageState extends State<LongListPage> {
      List<Map<String, int>> _elements = List<Map<String, int>>.generate(
          30, (int index) => {'name': index, 'isEven': index % 2 == 0 ? 0 : 1});
    
      List<Map<String, int>> _filterElements = [];
    
      @override
      void initState() {
        _filterElements = _elements;
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              TextButton(
                onPressed: () {
                  setState(() {
                    _filterElements = _elements.where(
                      (element) {
                        return element['name'] % 2 == 0;
                      },
                    ).toList();
                  });
                },
                child: Text('only even'),
              ),
              Expanded(
                child: GroupedListView<Map<String, int>, int>(
                  elements: _filterElements,
                  groupBy: (element) => element['isEven'],
                  separator: Divider(),
                  groupComparator: (value1, value2) {
                    return value1.compareTo(value2);
                  },
                  useStickyGroupSeparators: true,
                  groupSeparatorBuilder: (value) {
                    return Text(
                      value.toString(),
                      style: TextStyle(
                        backgroundColor: Colors.red,
                      ),
                    );
                  },
                  itemBuilder: (context, element) {
                    return Text(element['name'].toString());
                  },
                ),
              ),
            ],
          ),
        );
      }
    }
    

    When I scroll to the bottom of the list and then I try to filter the list content by pressing the "only even" button I get:

    RangeError (index): Invalid value: Not in inclusive range 0..14: 16 The relevant error-causing widget was GroupedListView<Map<String, int>, int>

    question 
    opened by easydo247 11
  • Scroll to Element

    Scroll to Element

    Based on incoming FCM messages i need to automatically scroll to a certain list element position based on the element's id (not index) it has in its data model. How can this be achieved with a GroupedListView?

    help wanted 
    opened by rivella50 9
  • Something is not right after updating to v3.0.1

    Something is not right after updating to v3.0.1

    Hello,

    I just updated my app with the latest version of the library and my grouped list is behaving strange.

    I noticed that if I don't add the floatingHeader param to false, then I get only the first groupSeparator item and the rest of the list is not visible.

    If I add the floatingHeader param to true then I get all the items of the grouped list with a sticky groupSeparator item which somehow has a transparent background. What am I doing wrong?

    And since I opened this thread I have a small question. I group my list after date but I would like to order it after date and time is that possible somehow?

    Thank you in advance.

    opened by MihaiRebegea 9
  • Sticky group separator shows wrong values

    Sticky group separator shows wrong values

    I have an issue when displaying a list with contacts names in Hebrew, the value inside the sticky group separator gets kind of stuck and not displaying the correct value.

    Example: demo-gif

    • The first letter of the names in the list is in the right.
    bug 
    opened by CripyIce 9
  • Exception when used inside SliverChildListDelegate

    Exception when used inside SliverChildListDelegate

    Hello, thanks for the lib!

    I'm having issues using GroupedListView inside a SliverChildListDelegate. Before, I was using ListView.separated and it was working properly.

    Some snippets to help:

    BEFORE: (working)

     @override
      Widget build(BuildContext context) {
        return BlocBuilder<EventBloc, EventState>(
          bloc: BlocProvider.of(context),
          builder: (BuildContext context, EventState state){
            if(state is EventLoading){
              return Column(children: [
                CircularProgressIndicator()
              ]);
            }else if(state is EventEmpty){
              return Column(
                children: <Widget>[
                  Text('No results :('),
                ],
              );
            }else if(state is EventLoaded){
              return ListView.separated(
                  controller: scrollController,
                  shrinkWrap: true,
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                  itemCount: state.hasMore ? state.event.length + 1 : state.event.length,
                  itemBuilder: (BuildContext context, int index) {
                    if(index >= state.event.length){
                      return Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Container(
                            padding: EdgeInsets.only(bottom: 12),
                            child: RaisedButton(
                              child: Text('Load More...'),
                              onPressed: (){
                                eventBloc.add(LoadMoreEvent());
                              },
                            ),
                          ),
                        ],
                      );
                    } else {
                      return ConferenceItem(event: state.event[index]);
                    }
                  });
            }else{
              return Container();
            }
          },
        );
    

    AFTER (not working):

    @override
      Widget build(BuildContext context) {
        return BlocBuilder<EventBloc, EventState>(
          bloc: BlocProvider.of(context),
          builder: (BuildContext context, EventState state){
            if(state is EventLoading){
              return Align(
                  child: CircularProgressIndicator()
              );
            }else if(state is EventEmpty){
              return Column(
                children: <Widget>[
                  Text('No results :('),
                ],
              );
            }else if(state is EventLoaded){
              return GroupedListView<Event, String>(
                  separator: Divider(),
                  elements: state.event,
    //              itemCount: state.hasMore ? state.event.length + 1 : state.event.length,
                  indexedItemBuilder: (BuildContext context, Event event, int index) {
                    if(index >= state.event.length){
                      return Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Container(
                            padding: EdgeInsets.only(bottom: 12),
                            child: RaisedButton(
                              child: Text('Load More...'),
                              onPressed: (){
                                eventBloc.add(LoadMoreEvent());
                              },
                            ),
                          ),
                        ],
                      );
                    } else {
                      return ConferenceItem(event: event);
                    }
                  },
                  groupSeparatorBuilder: (value) {
                    return Text('teste');
                  },
                  groupBy: (Event element) {
                    return element.country;
                  });
            }else{
              return Container();
            }
          },
        );
      }
    

    The parent component (which contains the ListView):

    SliverList(
                   delegate: SliverChildListDelegate([
                     Padding(
                       padding: const EdgeInsets.only(top: 16.0),
                       child: SearchBody(), <---- THIS IS THE ListView/GroupListView component
                     ),
                   ])
               )
    

    The exception I'm facing is the following:

    ════════ Exception caught by rendering library ═════════════════════════════════════════════════════
    The following assertion was thrown during performLayout():
    RenderFlex children have non-zero flex but incoming height constraints are unbounded.
    
    When a column is in a parent that does not provide a finite height constraint, for example if it is in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the vertical direction.
    These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.
    
    Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible children (using Flexible rather than Expanded). This will allow the flexible children to size themselves to less than the infinite remaining space they would otherwise be forced to take, and then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum constraints provided by the parent.
    
    If this message did not help you determine the problem, consider using debugDumpRenderTree():
      https://flutter.dev/debugging/#rendering-layer
      http://api.flutter.dev/flutter/rendering/debugDumpRenderTree.html
    The affected RenderFlex is: RenderFlex#acbea relayoutBoundary=up5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
      parentData: offset=Offset(0.0, 0.0) (can use size)
      constraints: BoxConstraints(w=411.4, 0.0<=h<=Infinity)
      size: MISSING
      direction: vertical
      mainAxisAlignment: start
      mainAxisSize: max
      crossAxisAlignment: center
      verticalDirection: down
    ...  child 1: RenderLimitedBox#a815b relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...    parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
    ...    constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=Infinity)
    ...    size: Size(411.4, 0.0)
    ...    maxWidth: 0.0
    ...    maxHeight: 0.0
    ...    child: RenderConstrainedBox#eb095 relayoutBoundary=up7 NEEDS-PAINT
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(0.0<=w<=411.4, h=0.0)
    ...      size: Size(411.4, 0.0)
    ...      additionalConstraints: BoxConstraints(biggest)
    ...  child 2: RenderRepaintBoundary#8e0c8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...    needs compositing
    ...    parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.tight
    ...    constraints: MISSING
    ...    size: MISSING
    ...    usefulness ratio: no metrics collected yet (never painted)
    ...    child: RenderCustomPaint#342ca NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...      parentData: <none>
    ...      constraints: MISSING
    ...      size: MISSING
    ...      child: RenderRepaintBoundary#bc4ab NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...        needs compositing
    ...        parentData: <none>
    ...        constraints: MISSING
    ...        size: MISSING
    ...        usefulness ratio: no metrics collected yet (never painted)
    ...        child: _RenderScrollSemantics#17174 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...          parentData: <none>
    ...          constraints: MISSING
    ...          semantic boundary
    ...          size: MISSING
    The creator information is set to: Column-[GlobalKey#e959e] ← GroupedListView<Event, String> ← BlocBuilder<EventBloc, EventState> ← SearchBody ← Padding ← RepaintBoundary ← IndexedSemantics ← NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← KeyedSubtree ← SliverList ← ⋯
    
    See also: https://flutter.dev/layout/
    
    If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
      https://github.com/flutter/flutter/issues/new?template=BUG.md
    The relevant error-causing widget was: 
      GroupedListView<Event, String> file:///Users/leonardo2204/project/flutter/confs_tech/lib/widgets/body.dart:57:18
    When the exception was thrown, this was the stack: 
    #0      RenderFlex.performLayout.<anonymous closure> (package:flutter/src/rendering/flex.dart:691:11)
    #1      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:718:10)
    #2      RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
    #3      RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:206:11)
    #4      RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)
    ...
    The following RenderObject was being processed when the exception was fired: RenderFlex#acbea relayoutBoundary=up5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...  parentData: offset=Offset(0.0, 0.0) (can use size)
    ...  constraints: BoxConstraints(w=411.4, 0.0<=h<=Infinity)
    ...  size: MISSING
    ...  direction: vertical
    ...  mainAxisAlignment: start
    ...  mainAxisSize: max
    ...  crossAxisAlignment: center
    ...  verticalDirection: down
    RenderObject: RenderFlex#acbea relayoutBoundary=up5 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
      parentData: offset=Offset(0.0, 0.0) (can use size)
      constraints: BoxConstraints(w=411.4, 0.0<=h<=Infinity)
      size: MISSING
      direction: vertical
      mainAxisAlignment: start
      mainAxisSize: max
      crossAxisAlignment: center
      verticalDirection: down
    ...  child 1: RenderLimitedBox#a815b relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...    parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
    ...    constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=Infinity)
    ...    size: Size(411.4, 0.0)
    ...    maxWidth: 0.0
    ...    maxHeight: 0.0
    ...    child: RenderConstrainedBox#eb095 relayoutBoundary=up7 NEEDS-PAINT
    ...      parentData: <none> (can use size)
    ...      constraints: BoxConstraints(0.0<=w<=411.4, h=0.0)
    ...      size: Size(411.4, 0.0)
    ...      additionalConstraints: BoxConstraints(biggest)
    ...  child 2: RenderRepaintBoundary#8e0c8 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...    needs compositing
    ...    parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.tight
    ...    constraints: MISSING
    ...    size: MISSING
    ...    usefulness ratio: no metrics collected yet (never painted)
    ...    child: RenderCustomPaint#342ca NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...      parentData: <none>
    ...      constraints: MISSING
    ...      size: MISSING
    ...      child: RenderRepaintBoundary#bc4ab NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...        needs compositing
    ...        parentData: <none>
    ...        constraints: MISSING
    ...        size: MISSING
    ...        usefulness ratio: no metrics collected yet (never painted)
    ...        child: _RenderScrollSemantics#17174 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    ...          parentData: <none>
    ...          constraints: MISSING
    ...          semantic boundary
    ...          size: MISSING
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    
    ════════ Exception caught by rendering library ═════════════════════════════════════════════════════
    RenderBox was not laid out: RenderFlex#acbea relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    'package:flutter/src/rendering/box.dart':
    Failed assertion: line 1687 pos 12: 'hasSize'
    The relevant error-causing widget was: 
      Padding file:///Users/leonardo2204/project/flutter/confs_tech/lib/bloc/home_page.dart:38:19
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    
    ════════ Exception caught by rendering library ═════════════════════════════════════════════════════
    The method '>' was called on null.
    Receiver: null
    Tried calling: >(1e-10)
    The relevant error-causing widget was: 
      GroupedListView<Event, String> file:///Users/leonardo2204/project/flutter/confs_tech/lib/widgets/body.dart:57:18
    ════════════════════════════════════════════════════════════════════════════════════════════════════
    

    For what it is worth, the code is open source: https://github.com/leonardo2204/confstech-flutter/blob/master/lib/widgets/body.dart#L40

    I'm suspecting this may be related to the Expanded widget wrapping the ListView, but I'm not 100% sure, I'll dig further.

    Thanks again!

    new feature 
    opened by leonardo2204 8
  • Order Descending Grouped Dates

    Order Descending Grouped Dates

    Hi,

    My code was runnning ok with previous versión of 4.0.0. After upgrading I lost scending ordenring of the groups. Items still ordenring descending but not the groups. If I only order by MMM yyyy is ok but if I order by dd MMMM yyyy then the groups order does not work. I have tryied differents combination with comparator but not succeed.

    GroupedListView(
                          key: const Key('changeLogGroupedList'),
                          elements: logItems,
                          floatingHeader: true,
                          addAutomaticKeepAlives: true,
                          useStickyGroupSeparators: true,
                          groupBy: (dynamic logItem) => DateFormat('dd MMMM yyyy')
                              .format(logItem.createdAt.toDate()),
                          groupComparator: (value1, value2) =>
                              value2.compareTo(value1),
                          itemComparator: (item1, item2) =>
                              item1.createdAt.compareTo(item2.createdAt),
                          order: GroupedListOrder.DESC,
                          groupSeparatorBuilder: (dynamic logItem) => SizedBox(
    
    opened by saguado69 6
  • How to list custom datatypes in group

    How to list custom datatypes in group

    `

    class record{
    
      String Name;
      int DayofBirth;
    
      record(String Name, int DayofBirth){
        Name=this.Name;
        DayofBirth=this.DayofBirth;
      }
    
    }
    

    Now I want the following list

     var lists=[
    
        record("Ashu",DateTime.thursday),
        record("Aniket",DateTime.monday),
        record("Eishu",DateTime.saturday),
        record("Keshav",DateTime.thursday),
    
    
      ];
    

    ` Into the grouped list according to DayofBirth

    This is my GroupListView `

    GroupedListView<dynamic,record>(
                    elements: lists,
                    groupBy: (element)=>element.DayofBirth,
                    groupSeparatorBuilder: _buildSperator,
                    itemBuilder: (context, element) => Text(element.Name),
                    order: GroupedListOrder.ASC,
                  ),
    Widget _buildSperator(dynamic groupByValue){
      return Text(groupByValue);
    
    }
    

    `

    opened by ashutosh840 6
  • Fixes update to version 3.0 of flutter.

    Fixes update to version 3.0 of flutter.

    This change will fix the error when using Flutter 3.0,

    : Warning: Operand of null-aware operation '!' has type 'WidgetsBinding' which excludes null. ../…/lib/grouped_list.dart:264

    • 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('../../../flutter/packages/flutter/lib/src/widgets/binding.dart'). package:flutter/…/widgets/binding.dart:1 WidgetsBinding.instance!.addPostFrameCallback((_) {
    opened by UP929312 5
  • Feature/distinct key parent child

    Feature/distinct key parent child

    The key of GroupedListView is also used as the key for child ListView, which leads to an exception. I removed the duplication of key usage in ListView.

    opened by kristofb 0
  • how i can get index of group separator

    how i can get index of group separator

    Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

    Describe the solution you'd like A clear and concise description of what you want to happen.

    opened by nguyennhattan24 0
  • Group separator does not change background on dark mode

    Group separator does not change background on dark mode

    Describe the bug When setting theme to dark mode, the group separator background color remains at white, and this makes the text almost impossible to read. I should mention this is with useStickyGroupSeparators = true. The issue is with the sticky group separator .

    Expected behavior When setting theme to dark mode, the sticky group separator background color should be the same as the dark mode theme background color (or transparent)

    Information:

    • Dart version: 2.18.4
    • Flutter version: 3.3.8
    • Platform: Android
    • Package version: 5.1.2
    bug 
    opened by ken-salterdiazsolutions 0
  • [bugfix] fix RangeError when _sortedElements is empty

    [bugfix] fix RangeError when _sortedElements is empty

    when _sortedElements is empty throw RangeError.

    The following RangeError was thrown during a scheduler callback: RangeError (index): Invalid value: Valid value range is empty: 0

    When the exception was thrown, this was the stack: #0 List.[] (dart:core-patch/growable_array.dart:264:36) #1 _GroupedListViewState._scrollListener (package:grouped_list/grouped_list.dart:366:48) #2 _GroupedListViewState.build. (package:grouped_list/grouped_list.dart:272:9) #3 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15) #4 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:9) #5 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5) #6 _invoke (dart:ui/hooks.dart:148:13) #7 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)

    opened by magazmj 0
Releases(v5.1.2)
Flutter package to hide out whole application or sections if you are not paid for the job done.

not_paid Worried about your payment? Using this package you can provide a non paid version of your app to the client that consistently starts fading o

hd-motion 11 Nov 30, 2021
An extension of the Flutter ListView widget for incrementally loading items upon scrolling

incrementally_loading_listview An extension of the Flutter ListView widget for incrementally loading items upon scrolling. This could be used to load

Michael Bui 174 Sep 27, 2022
A ListView that allows you to group list items and support headers like iOS UITableView section.

GroupListView package for Flutter. A ListView that allows you to group list items and support headers like iOS UITableView section. Features List Item

Daniel Ioannou 73 Nov 21, 2022
A loading more list which supports ListView,GridView,WaterfallFlow and Slivers.

loading_more_list A loading more list which supports ListView,GridView,WaterfallFlow and Slivers. Language: English | 中文简体 Web demo for LoadingMoreLis

FlutterCandies 292 Dec 19, 2022
Flutter Scrollable Widgets like ListView,GridView or powerful CustomScrollView can't nest inner scrollview

Introduction Flutter Scrollable Widgets like ListView,GridView or powerful CustomScrollView can't nest inner scrollview. If Nested, inner scrollview w

jaysonss 5 Aug 28, 2022
A Demo application📱 which stores User feedback from 💙Flutter application into Google Sheets🗎 using Google AppScript.

?? Flutter ?? to Google Sheets ?? A Demo application which stores User feedback from Flutter application into Google Sheets using Google AppScript. Yo

Shreyas Patil 289 Dec 28, 2022
Easy to use text widget for Flutter apps, which converts inlined urls into working, clickable links

LinkText Easy to use text widget for Flutter apps, which converts inlined URLs into clickable links. Allows custom styling. Usage LinkText widget does

Aleksander Woźniak 20 Nov 4, 2022
Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls into your app with only a few lines of code.

Call Kit (ZegoUIKitPrebuiltCall) Call Kit is a prebuilt feature-rich call component, which enables you to build one-on-one and group voice/video calls

ZEGOCLOUD 9 Dec 26, 2022
A Flutter widget that forces the device rotates into the set of orientations the application interface can be displayed in.

A Flutter widget that forces the device rotates into the set of orientations the application interface can be displayed in. Features Force device keep

De Men 1 Nov 30, 2021
Polymaker is an application that can create polygon locations dynamically in mobile apps and save the data into SQFlite to be permanent.

Polymaker Polymaker is an application that can create polygon locations dynamically in mobile apps and save the data into SQFlite to be permanent. Ins

Yusril Rapsanjani 15 Apr 17, 2022
Flutter package to simplify pagination of list of items from the internet.

PaginationView Installing In your pubspec.yaml dependencies: pagination_view: ^2.0.0-nullsafety.0 import 'package:pagination_view/pagination_view.da

Venkatesh Prasad 151 Dec 29, 2022
Flutter package that provide selectable items in list like Column

vertical_picker vertical_picker is flutter package that you can use it as item selector. users with this package be able to select item that is in ver

Sajad Rahimi 6 Nov 19, 2022
A Flutter plugin that lists native gallery items.

Media Gallery plugin for Flutter A Flutter plugin that lists native gallery items. Installation First, add media_gallery as a dependency in your pubsp

Aloïs Deniel 84 Dec 7, 2022
Flutter package to simplify pagination of list of items from the internet.

PaginationView Installing In your pubspec.yaml dependencies: pagination_view: ^2.0.0-nullsafety.0 import 'package:pagination_view/pagination_view.da

Venkatesh Prasad 151 Dec 29, 2022
Receipt app to list items on a receipt with AI receipt-interpreter. Made with Flutter by Futhark AS

Receipt Recognizer Summary Extracts data from an image of a receipt, storing it in a structured format. The application is created using Flutter and t

Futhark 2 Dec 15, 2022
An app that opens Facebook, Google, Youtube by Click on the navigation bar items specifically for each.

navbutton A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started if thi

dev_allauddin 3 Feb 3, 2022
Lost and Found is an app to help people find their lost items.

lost_and_found A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started i

SonaCodeur 1 Jan 20, 2022
A grid that supports both dragging and tapping to select its items

drag_select_grid_view A grid that supports both dragging and tapping to select its items. Basic usage DragSelectGridView constructor is very similar t

Hugo Passos 121 Dec 11, 2022