Skip to content

Commit

Permalink
use different constructors for separated list
Browse files Browse the repository at this point in the history
  • Loading branch information
matteo.gentile committed Aug 3, 2023
1 parent 14ccaf2 commit 1f856b6
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 32 deletions.
102 changes: 81 additions & 21 deletions lib/src/implicitly_animated_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ class ImplicitlyAnimatedList<E extends Object> extends StatelessWidget {

@override
Widget build(BuildContext context) {
final separatorBuilder = this.separatorBuilder;

return CustomScrollView(
scrollDirection: scrollDirection,
reverse: reverse,
Expand All @@ -159,18 +161,30 @@ class ImplicitlyAnimatedList<E extends Object> extends StatelessWidget {
slivers: <Widget>[
SliverPadding(
padding: padding ?? const EdgeInsets.all(0),
sliver: SliverImplicitlyAnimatedList<E>(
items: items,
itemBuilder: itemBuilder,
separatorBuilder: separatorBuilder,
areItemsTheSame: areItemsTheSame,
updateItemBuilder: updateItemBuilder,
removeItemBuilder: removeItemBuilder,
insertDuration: insertDuration,
removeDuration: removeDuration,
updateDuration: updateDuration,
spawnIsolate: spawnIsolate,
),
sliver: separatorBuilder == null
? SliverImplicitlyAnimatedList<E>(
items: items,
itemBuilder: itemBuilder,
areItemsTheSame: areItemsTheSame,
updateItemBuilder: updateItemBuilder,
removeItemBuilder: removeItemBuilder,
insertDuration: insertDuration,
removeDuration: removeDuration,
updateDuration: updateDuration,
spawnIsolate: spawnIsolate,
)
: SliverImplicitlyAnimatedList<E>.separated(
items: items,
itemBuilder: itemBuilder,
separatorBuilder: separatorBuilder,
areItemsTheSame: areItemsTheSame,
updateItemBuilder: updateItemBuilder,
removeItemBuilder: removeItemBuilder,
insertDuration: insertDuration,
removeDuration: removeDuration,
updateDuration: updateDuration,
spawnIsolate: spawnIsolate,
),
),
],
);
Expand All @@ -189,6 +203,53 @@ class SliverImplicitlyAnimatedList<E extends Object>
/// The [itemBuilder] callback is used to build each child as needed. The parent must
/// be a [Reorderable] widget.
///
/// The [areItemsTheSame] callback is called by the DiffUtil to decide whether two objects
/// represent the same item. For example, if your items have unique ids, this method should
/// check their id equality.
///
/// The [onReorderFinished] callback is called in response to when the dragged item has
/// been released and animated to its final destination. Here you should update
/// the underlying data in your model/bloc/database etc.
///
/// The [spawnIsolate] flag indicates whether to spawn a new isolate on which to
/// calculate the diff between the lists. Usually you wont have to specify this
/// value as the MyersDiff implementation will use its own metrics to decide, whether
/// a new isolate has to be spawned or not for optimal performance.
/// {@endtemplate}
const SliverImplicitlyAnimatedList({
Key? key,
required List<E> items,
required AnimatedItemBuilder<Widget, E> itemBuilder,
required ItemDiffUtil<E> areItemsTheSame,
RemovedItemBuilder<Widget, E>? removeItemBuilder,
UpdatedItemBuilder<Widget, E>? updateItemBuilder,
Duration insertDuration = const Duration(milliseconds: 500),
Duration removeDuration = const Duration(milliseconds: 500),
Duration updateDuration = const Duration(milliseconds: 500),
bool? spawnIsolate,
}) : super(
key: key,
items: items,
itemBuilder: itemBuilder,
delegateBuilder: null,
areItemsTheSame: areItemsTheSame,
removeItemBuilder: removeItemBuilder,
updateItemBuilder: updateItemBuilder,
insertDuration: insertDuration,
removeDuration: removeDuration,
updateDuration: updateDuration,
spawnIsolate: spawnIsolate,
);

/// Creates a Flutter Sliver that implicitly animates between the changes of two lists.
///
/// {@template implicitly_animated_reorderable_list.constructor}
/// The [items] parameter represents the current items that should be displayed in
/// the list.
///
/// The [itemBuilder] callback is used to build each child as needed. The parent must
/// be a [Reorderable] widget.
///
/// The [separatorBuilder] is the widget that gets placed between
/// itemBuilder(context, index) and itemBuilder(context, index + 1).
///
Expand All @@ -205,12 +266,12 @@ class SliverImplicitlyAnimatedList<E extends Object>
/// value as the MyersDiff implementation will use its own metrics to decide, whether
/// a new isolate has to be spawned or not for optimal performance.
/// {@endtemplate}
SliverImplicitlyAnimatedList({
SliverImplicitlyAnimatedList.separated({
Key? key,
required List<E> items,
required AnimatedItemBuilder<Widget, E> itemBuilder,
required ItemDiffUtil<E> areItemsTheSame,
NullableIndexedWidgetBuilder? separatorBuilder,
required NullableIndexedWidgetBuilder separatorBuilder,
RemovedItemBuilder<Widget, E>? removeItemBuilder,
UpdatedItemBuilder<Widget, E>? updateItemBuilder,
Duration insertDuration = const Duration(milliseconds: 500),
Expand All @@ -221,13 +282,12 @@ class SliverImplicitlyAnimatedList<E extends Object>
key: key,
items: items,
itemBuilder: itemBuilder,
delegateBuilder: separatorBuilder == null
? null
: ((builder, itemCount) => SliverChildSeparatedBuilderDelegate(
itemBuilder: builder,
separatorBuilder: separatorBuilder,
itemCount: itemCount,
)),
delegateBuilder: (builder, itemCount) =>
SliverChildSeparatedBuilderDelegate(
itemBuilder: builder,
separatorBuilder: separatorBuilder,
itemCount: itemCount,
),
areItemsTheSame: areItemsTheSame,
removeItemBuilder: removeItemBuilder,
updateItemBuilder: updateItemBuilder,
Expand Down
87 changes: 76 additions & 11 deletions lib/src/implicitly_animated_reorderable_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,72 @@ class ImplicitlyAnimatedReorderableList<E extends Object>
/// on performance and autoscrolling.
final Widget? footer;

/// Creates a Flutter ListView that implicitly animates between the changes of two lists with
/// the support to reorder its items.
///
/// The [items] parameter represents the current items that should be displayed in
/// the list.
///
/// The [itemBuilder] callback is used to build each child as needed. The parent must
/// be a [Reorderable] widget.
///
/// The [areItemsTheSame] callback is called by the DiffUtil to decide whether two objects
/// represent the same item. For example, if your items have unique ids, this method should
/// check their id equality.
///
/// The [onReorderFinished] callback is called in response to when the dragged item has
/// been released and animated to its final destination. Here you should update
/// the underlying data in your model/bloc/database etc.
///
/// The [spawnIsolate] flag indicates whether to spawn a new isolate on which to
/// calculate the diff between the lists. Usually you wont have to specify this
/// value as the MyersDiff implementation will use its own metrics to decide, whether
/// a new isolate has to be spawned or not for optimal performance.
const ImplicitlyAnimatedReorderableList({
Key? key,
required List<E> items,
required AnimatedItemBuilder<Reorderable, E> itemBuilder,
required ItemDiffUtil<E> areItemsTheSame,
RemovedItemBuilder<Reorderable, E>? removeItemBuilder,
UpdatedItemBuilder<Reorderable, E>? updateItemBuilder,
Duration insertDuration = const Duration(milliseconds: 500),
Duration removeDuration = const Duration(milliseconds: 500),
Duration updateDuration = const Duration(milliseconds: 500),
Duration? liftDuration,
Duration? settleDuration,
bool? spawnIsolate,
this.reverse = false,
this.scrollDirection = Axis.vertical,
this.controller,
this.primary,
this.physics,
this.shrinkWrap = false,
this.padding,
this.reorderDuration = const Duration(milliseconds: 300),
this.onReorderStarted,
required this.onReorderFinished,
this.header,
this.footer,
}) : liftDuration = liftDuration ?? reorderDuration,
settleDuration = settleDuration ?? liftDuration ?? reorderDuration,
assert(
reorderDuration <= const Duration(milliseconds: 1500),
'The drag duration should not be longer than 1500 milliseconds.',
),
super(
key: key,
items: items,
itemBuilder: itemBuilder,
delegateBuilder: null,
areItemsTheSame: areItemsTheSame,
removeItemBuilder: removeItemBuilder,
updateItemBuilder: updateItemBuilder,
insertDuration: insertDuration,
removeDuration: removeDuration,
updateDuration: updateDuration,
spawnIsolate: spawnIsolate,
);

/// Creates a Flutter ListView that implicitly animates between the changes of two lists with
/// the support to reorder its items.
///
Expand All @@ -152,12 +218,12 @@ class ImplicitlyAnimatedReorderableList<E extends Object>
/// calculate the diff between the lists. Usually you wont have to specify this
/// value as the MyersDiff implementation will use its own metrics to decide, whether
/// a new isolate has to be spawned or not for optimal performance.
ImplicitlyAnimatedReorderableList({
ImplicitlyAnimatedReorderableList.separated({
Key? key,
required List<E> items,
required AnimatedItemBuilder<Reorderable, E> itemBuilder,
required ItemDiffUtil<E> areItemsTheSame,
NullableIndexedWidgetBuilder? separatorBuilder,
required NullableIndexedWidgetBuilder separatorBuilder,
RemovedItemBuilder<Reorderable, E>? removeItemBuilder,
UpdatedItemBuilder<Reorderable, E>? updateItemBuilder,
Duration insertDuration = const Duration(milliseconds: 500),
Expand Down Expand Up @@ -188,13 +254,12 @@ class ImplicitlyAnimatedReorderableList<E extends Object>
key: key,
items: items,
itemBuilder: itemBuilder,
delegateBuilder: separatorBuilder == null
? null
: ((builder, itemCount) => SliverChildSeparatedBuilderDelegate(
itemBuilder: builder,
separatorBuilder: separatorBuilder,
itemCount: itemCount,
)),
delegateBuilder: (builder, itemCount) =>
SliverChildSeparatedBuilderDelegate(
itemBuilder: builder,
separatorBuilder: separatorBuilder,
itemCount: itemCount,
),
areItemsTheSame: areItemsTheSame,
removeItemBuilder: removeItemBuilder,
updateItemBuilder: updateItemBuilder,
Expand Down Expand Up @@ -329,7 +394,7 @@ class ImplicitlyAnimatedReorderableListState<E extends Object>
if (dragKey == null || dragItem == null) return;

// Allow the dragged item to be overscrolled to allow for
// continous scrolling while in drag.
// continuous scrolling while in drag.
final overscrollBound =
_canScroll && !(hasHeader || hasFooter) ? _dragSize : 0;
// Constrain the dragged item to the bounds of the list.
Expand Down Expand Up @@ -718,7 +783,7 @@ class ImplicitlyAnimatedReorderableListState<E extends Object>
final size = dragItem?.size;

// Determine if the dragged widget should be hidden
// immidiately, or with on frame delay in order to
// immediately, or with on frame delay in order to
// avoid item flash.
final mustRebuild = _dragWidget == null;

Expand Down

0 comments on commit 1f856b6

Please sign in to comment.