implicitly_animated_reorderable_list 0.1.7

Implicitly Animated Reorderable List #

A Flutter ListView that implicitly calculates the changes between two lists using the MyersDiff algorithm and animates between them for you. The ImplicitlyAnimatedReorderableList adds reordering support to its items with fully custom animations.

Demo

Click here to view the full example.

Installing #

Add it to your pubspec.yaml file:

dependencies:
  implicitly_animated_reorderable_list: ^0.1.7

Install packages from the command line

flutter packages get

Usage #

The package contains two ListViews: ImplicitlyAnimatedList which is the base class and offers implicit animation for item insertions, removals as well as updates, and ImplicitlyAnimatedReorderableList which extends the ImplicitlyAnimatedList and adds reordering support to its items. See examples below on how to use them.

ImplicitlyAnimatedList #

ImplicitlyAnimatedList is based on AnimatedList and uses the MyersDiff algorithm to calculate the difference between two lists and calls insertItem and removeItem on the AnimatedListState for you.

Example #

// Specify the generic type of the data in the list.
ImplicitlyAnimatedList<MyGenericType>(
  // The current items in the list.
  items: items,
  // Called by the DiffUtil to decide whether two object represent the same item.
  // For example, if your items have unique ids, this method should check their id equality.
  areItemsTheSame: (a, b) => a.id == b.id,
  // Called, as needed, to build list item widgets.
  // List items are only built when they're scrolled into view.
  itemBuilder: (context, animation, item, index) {
    // Specifiy a transition to be used by the ImplicitlyAnimatedList.
    // In this case a custom transition.
    return SizeFadeTranstion(
      sizeFraction: 0.7,
      curve: Curves.easeInOut,
      animation: animation,
      child: Text(item.name),
    ); 
  },
  // An optional builder when an item was removed from the list.
  // If not specified, the List uses the itemBuilder with 
  // the animation reversed.
  removedItemBuilder: (context, animation, oldItem) {
    return FadeTransition(
      opacity: animation,
      child: Text(oldItem.name),
    );
  },
);

Note as AnimatedList doesn't support item moves, a move is handled by removing the item from the old index and inserting it at the new index.

ImplicitlyAnimatedReorderableList #

ImplicitlyAnimatedReorderableList is based on ImplicitlyAnimatedList and adds reordering support to the list.

Example #

ImplicitlyAnimatedReorderableList<MyGenericType>(
  items: items,
  areItemsTheSame: (oldItem, newItem) => oldItem.id == newItem.id,
  onReorderFinished: (item, from, to, newItems) {
    // Remember to update the underlying data when the list has been
    // reordered.
    setState(() {
      items
        ..clear()
        ..addAll(newItems);
    });
  },
  itemBuilder: (context, itemAnimation, item, index) {
    // Each item must be wrapped in a Reorderable widget.
    return Reorderable(
      // Each item must have an unique key.
      key: ValueKey(item),
      // The animation of the Reorderable builder can be used to
      // change to appearance of the item between dragged and normal
      // state. For example to add elevation when the item is being dragged.
      // This is not to be confused with the animation of the itemBuilder.
      // Implicit animations (like AnimatedContainer) are sadly not yet supported.
      builder: (context, dragAnimation, inDrag) {
        final t = dragAnimation.value;
        final elevation = lerpDouble(0, 8, t);
        final color = Color.lerp(Colors.white, Colors.white.withOpacity(0.8), t);

        return SizeFadeTranstion(
          sizeFraction: 0.7,
          curve: Curves.easeInOut,
          animation: itemAnimation,
          child: Material(
            color: color,
            elevation: elevation,
            type: MaterialType.transparency,
            child: ListTile(
              title: Text(item.name),
              // The child of a Handle can initialize a drag/reorder.
              // This could for example be an Icon or the whole item itself. You can
              // use the delay parameter to specify the duration for how long a pointer
              // must press the child, until it can be dragged.
              trailing: Handle(
                delay: const Duration(milliseconds: 100),
                child: Icon(
                  Icons.list,
                  color: Colors.grey,
                ),
              ),
            ),
          ),
        );
      },
    );
  },
);

For a more in depth example click here.

Caveats #

Note that this package is still in its very early phase and not enough testing has been done to guarantee stability.
Also note that computing the diff between two very large lists my take significant amount of time (the computation is done on a background isolate though).

Acknowledgements #

The diff algorithm that ImplicitlyAnimatedList uses was written by Dawid Bota at GitLab.

Roadmap #

You can take a look at the Roadmap to see which featues I am working on or plan to implement in future versions.

Changelog #

0.1.4 #

  • Made Handle scroll aware to only initiate a drag when the scroll position didn't change.
  • Added horizontal scrollDirection support for ImplicitlyAnimatedReorderableList

0.1.0 #

  • Initial release

example/README.md

example #

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  implicitly_animated_reorderable_list: ^0.1.7

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:implicitly_animated_reorderable_list/implicitly_animated_reorderable_list.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
75
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
87
Learn more about scoring.

We analyzed this package on Feb 23, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.5
  • Flutter: 1.12.13+hotfix.7

Health suggestions

Format lib/implicitly_animated_reorderable_list.dart.

Run flutter format to format lib/implicitly_animated_reorderable_list.dart.

Format lib/src/diff/diff.dart.

Run flutter format to format lib/src/diff/diff.dart.

Format lib/src/diff/diff_callback.dart.

Run flutter format to format lib/src/diff/diff_callback.dart.

Fix additional 13 files with analysis or formatting issues.

Additional issues in the following files:

  • lib/src/diff/diff_delegate.dart (Run flutter format to format lib/src/diff/diff_delegate.dart.)
  • lib/src/diff/diff_model.dart (Run flutter format to format lib/src/diff/diff_model.dart.)
  • lib/src/diff/myers_diff.dart (Run flutter format to format lib/src/diff/myers_diff.dart.)
  • lib/src/diff/path_node.dart (Run flutter format to format lib/src/diff/path_node.dart.)
  • lib/src/handle.dart (Run flutter format to format lib/src/handle.dart.)
  • lib/src/implicitly_animated_list.dart (Run flutter format to format lib/src/implicitly_animated_list.dart.)
  • lib/src/implicitly_animated_list_base.dart (Run flutter format to format lib/src/implicitly_animated_list_base.dart.)
  • lib/src/implicitly_animated_reorderable_list.dart (Run flutter format to format lib/src/implicitly_animated_reorderable_list.dart.)
  • lib/src/reorderable.dart (Run flutter format to format lib/src/reorderable.dart.)
  • lib/src/src.dart (Run flutter format to format lib/src/src.dart.)
  • lib/src/util/handler.dart (Run flutter format to format lib/src/util/handler.dart.)
  • lib/src/util/invisible.dart (Run flutter format to format lib/src/util/invisible.dart.)
  • lib/src/util/util.dart (Run flutter format to format lib/src/util/util.dart.)

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
async ^2.4.0 2.4.0
flutter 0.0.0
meta ^1.1.8 1.1.8
Transitive dependencies
collection 1.14.11 1.14.12
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test