Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: determine under the hood the axis of size transition #9

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.5.2
* feat: determine the axis of SizeTransition under the hood
* feat(widgetbook): added axis knob for all scrollable widgets

# 0.5.1
* fix: `idMapper` not assigned to `ItemsEntity` after calling `ItemsNotifier.updateValue()`
* fix: item not marked as removed on move event when index did not changed
Expand Down
27 changes: 18 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,31 @@ Also, you can extend `AnimatedScrollView`, and create your own
implementation, using the API of this package.

## TODO:
- [x] Simultaneously removing and inserting item when moving([#35618](https://github.com/flutter/flutter/issues/35618))
- [x] Write documentation
- [ ] For `GridView` and `PageView`: animate items, rebuild of which is caused by another items modification event
- [ ] Set default axis for `SizeAndFadeTransition` to axis of the scrollable([#100931](https://github.com/flutter/flutter/issues/100931))
- [ ] Cover all code with tests
- [x] AnimatedPageView([#58959](https://github.com/flutter/flutter/issues/58959))?
- [X] Wrap ItemWidget in `SizedAndFadeTransition` and `PointerIgnorer` by default?
- [x] Widgetbook with live demo examples

Status |Task Name
:------:|----
✅|Simultaneously removing and inserting item when moving([#35618](https://github.com/flutter/flutter/issues/35618))
✅|Write documentation
⬜|For `GridView` and `PageView`: animate items, rebuild of which is caused by another items modification event
✅|Set default axis for `SizeAndFadeTransition` to axis of the scrollable[#100931](https://github.com/flutter/flutter/issues/100931#issuecomment-1120515790)
⬜|Cover all code with tests
✅|AnimatedPageView([#58959](https://github.com/flutter/flutter/issues/58959))?
✅|Wrap ItemWidget in `SizedAndFadeTransition` and `PointerIgnorer` by default?
✅|Widgetbook with live demo examples

## Installation 💻

Add `animated_scroll_view` to your `pubspec.yaml`:

```
flutter pub add animated_scroll_view
```

or manually:

```yaml
dependencies:
animated_scroll_view: ^0.5.0
animated_scroll_view: ^<latest version>
```

Install it:
Expand Down
22 changes: 19 additions & 3 deletions lib/src/widgets/transitions/size_and_fade_transition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class SizeAndFadeTransition extends StatelessWidget {
super.key,
required this.child,
required this.animation,
this.sizeTransitionAxis = Axis.vertical,
this.sizeTransitionAxis,
this.sizeTransitionAxisAlignment = 0,
});

Expand All @@ -29,8 +29,20 @@ class SizeAndFadeTransition extends StatelessWidget {

/// [Axis.horizontal] if [SizeTransition.sizeFactor] modifies the width,
/// otherwise [Axis.vertical].
///
/// This parameter is optional because if the axis was not specified
/// explicitly, it will be determined under the hood
/// by [Scrollable.of(context).axisDirection].
///
/// If the axis was not passed explicitly, and
/// [Scrollable.of(context)?.axisDirection], for some reason, returns `null`,
/// then [kDefaultTransitionAxis] is used.
@protected
final Axis sizeTransitionAxis;
final Axis? sizeTransitionAxis;

/// Default size transition axis, which is used when the axis is not specified
/// explicitly, and [Scrollable.of(context).axisDirection] returns `null`.
static const kDefaultTransitionAxis = Axis.vertical;

/// Describes how to align the child along the axis that
/// [SizeTransition.sizeFactor] is modifying.
Expand All @@ -41,9 +53,13 @@ class SizeAndFadeTransition extends StatelessWidget {

@override
Widget build(BuildContext context) {
final axisDirection = Scrollable.of(context)?.axisDirection;
final axis =
axisDirection == null ? null : axisDirectionToAxis(axisDirection);

return SizeTransition(
sizeFactor: animation,
axis: sizeTransitionAxis,
axis: sizeTransitionAxis ?? axis ?? kDefaultTransitionAxis,
axisAlignment: sizeTransitionAxisAlignment,
child: FadeTransition(
opacity: animation,
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Scrollable widgets, that helps you easily animate items removing, i
repository: https://github.com/radomir9720/animated_scroll_view
homepage: https://github.com/radomir9720/animated_scroll_view

version: 0.5.1
version: 0.5.2

environment:
sdk: ">=2.18.0 <3.0.0"
Expand Down
16 changes: 16 additions & 0 deletions widgetbook_app/lib/utils/knobs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,20 @@ extension KnobsExtension on BuildContext {
description: description,
);
}

Axis get axis {
return knobs.options<Axis>(
label: 'Axis',
options: const [
Option(
label: 'Vertical',
value: Axis.vertical,
),
Option(
label: 'Horizontal',
value: Axis.horizontal,
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import 'package:flutter/material.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
import 'package:widgetbook_app/widgets/scrollables/models/my_model.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/controls_wrapper.dart';
import 'package:widgetbook_app/utils/knobs.dart';

@WidgetbookUseCase(name: 'Default', type: AnimatedGridView)
Widget buildAnimatedGridView(BuildContext context) {
return AnimatedScrollViewControlsWrapper(
forceNotifyOnMoveAndRemove: true,
viewBuilder: (itemsNotifier, eventController, items) {
return AnimatedGridView<MyModel>(
scrollDirection: context.axis,
itemsNotifier: itemsNotifier,
eventController: eventController,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
Expand All @@ -20,7 +22,12 @@ Widget buildAnimatedGridView(BuildContext context) {
itemBuilder: (item) {
return ColoredBox(
color: item.color,
child: Center(child: Text('ItemId: ${item.id}')),
child: Center(
child: Text(
'ItemId: ${item.id}',
textAlign: TextAlign.center,
),
),
);
},
items: items,
Expand Down
15 changes: 6 additions & 9 deletions widgetbook_app/lib/widgets/scrollables/animated_list_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,22 @@ import 'package:animated_scroll_view/animated_scroll_view.dart';
import 'package:flutter/material.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/controls_wrapper.dart';
import 'package:widgetbook_app/utils/knobs.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/list_view_item.dart';

@WidgetbookUseCase(name: 'Default', type: AnimatedListView)
Widget buildAnimatedListView(BuildContext context) {
return AnimatedScrollViewControlsWrapper(
viewBuilder: (itemsNotifier, eventController, items) {
final axis = context.axis;

return AnimatedListView(
eventController: eventController,
itemsNotifier: itemsNotifier,
scrollDirection: axis,
idMapper: (object) => object.id.toString(),
items: items,
itemBuilder: (item) {
return ListTile(
leading: SizedBox.square(
dimension: 20,
child: ColoredBox(color: item.color),
),
title: Text('ItemId: ${item.id}'),
);
},
itemBuilder: (item) => ListViewItem(axis: axis, item: item),
);
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:animated_scroll_view/animated_scroll_view.dart';
import 'package:flutter/widgets.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/controls_wrapper.dart';
import 'package:widgetbook_app/utils/knobs.dart';

@WidgetbookUseCase(name: 'Default', type: AnimatedPageView)
Widget buildAnimatedPageView(BuildContext context) {
Expand All @@ -11,6 +12,7 @@ Widget buildAnimatedPageView(BuildContext context) {
viewBuilder: (itemsNotifier, eventController, items) {
return AnimatedPageView(
items: items,
scrollDirection: context.axis,
itemsNotifier: itemsNotifier,
eventController: eventController,
idMapper: (object) => object.id.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import 'package:animated_scroll_view/animated_scroll_view.dart';
import 'package:flutter/widgets.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/controls_wrapper.dart';
import 'package:widgetbook_app/utils/knobs.dart';

@WidgetbookUseCase(name: 'Default', type: SliverAnimatedGridView)
Widget buildSliverAnimatedGridView(BuildContext context) {
return AnimatedScrollViewControlsWrapper(
forceNotifyOnMoveAndRemove: true,
viewBuilder: (itemsNotifier, eventController, items) {
return CustomScrollView(
scrollDirection: context.axis,
slivers: [
SliverAnimatedGridView(
eventController: eventController,
Expand All @@ -17,7 +19,12 @@ Widget buildSliverAnimatedGridView(BuildContext context) {
itemBuilder: (item) {
return ColoredBox(
color: item.color,
child: Center(child: Text('ItemId: ${item.id}')),
child: Center(
child: Text(
'ItemId: ${item.id}',
textAlign: TextAlign.center,
),
),
);
},
items: items,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@ import 'package:animated_scroll_view/animated_scroll_view.dart';
import 'package:flutter/material.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/controls_wrapper.dart';
import 'package:widgetbook_app/widgets/scrollables/widgets/list_view_item.dart';
import 'package:widgetbook_app/utils/knobs.dart';

@WidgetbookUseCase(name: 'Default', type: SliverAnimatedListView)
Widget buildSliverAnimatedListView(BuildContext context) {
return AnimatedScrollViewControlsWrapper(
viewBuilder: (itemsNotifier, eventController, items) {
final axis = context.axis;

return CustomScrollView(
scrollDirection: axis,
slivers: [
SliverAnimatedListView(
itemsNotifier: itemsNotifier,
eventController: eventController,
idMapper: (object) => object.id.toString(),
itemBuilder: (item) {
return ListTile(
leading: SizedBox.square(
dimension: 20,
child: ColoredBox(color: item.color),
),
title: Text('ItemId: ${item.id}'),
);
},
itemBuilder: (item) => ListViewItem(axis: axis, item: item),
items: items,
),
],
Expand Down
38 changes: 38 additions & 0 deletions widgetbook_app/lib/widgets/scrollables/widgets/list_view_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:widgetbook_app/widgets/scrollables/models/my_model.dart';

class ListViewItem extends StatelessWidget {
const ListViewItem({super.key, required this.axis, required this.item});

@protected
final Axis axis;

@protected
final MyModel item;

@override
Widget build(BuildContext context) {
if (axis == Axis.horizontal) {
return ColoredBox(
color: item.color,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Center(
child: Text(
'ItemId:\n${item.id}',
textAlign: TextAlign.center,
),
),
),
);
}

return ListTile(
leading: SizedBox.square(
dimension: 20,
child: ColoredBox(color: item.color),
),
title: Text('ItemId: ${item.id}'),
);
}
}