Skip to content

Commit 517ecf3

Browse files
committed
add documentation and bump to version 0.3.0
1 parent 86c17f5 commit 517ecf3

File tree

5 files changed

+110
-36
lines changed

5 files changed

+110
-36
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 0.3.0
2+
## Added
3+
* The `closeOnTap` argument on slide actions to close when a action has been tapped.
4+
* The `closeOnScroll` argument on `Slidable` to close when the nearest `Scrollable` starts to scroll.
5+
* The static `Slidable.of` function.
6+
7+
## Changed
8+
* The `dragExtent` field in `SlidableDelegateContext` has been changed to `dragSign`.
9+
110
## 0.2.0
211
### Added
312
* `Slidable.builder` constructor.

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ A Flutter implementation of slidable list item with left and right slide actions
1414
* 2 built-in slide action widget.
1515
* You can easily create you custom layouts and animations.
1616
* You can use a builder to create your slide actions if you want special effects during animation.
17+
* Close when a slide action has been tapped (overridable).
18+
* Close when the nearest `Scrollable` starts to scroll (overridable).
1719

1820
## Getting started
1921

@@ -22,7 +24,7 @@ In the `pubspec.yaml` of your flutter project, add the following dependency:
2224
```yaml
2325
dependencies:
2426
...
25-
flutter_slidable: "^0.2.0"
27+
flutter_slidable: "^0.3.0"
2628
```
2729
2830
In your library add the following import:
@@ -52,7 +54,6 @@ A `direction` parameter let you choose if you want actions to appear when you sl
5254

5355
```dart
5456
new Slidable(
55-
key: Key('$3'),
5657
delegate: new SlidableDrawerDelegate(),
5758
actionExtentRatio: 0.25,
5859
child: new Container(
@@ -133,6 +134,16 @@ The slide actions stretch while the item is sliding:
133134

134135
![Overview](https://raw.githubusercontent.com/letsar/flutter_slidable/master/doc/images/slidable_stretch.gif)
135136

137+
#### How to prevent my slide action to close after it has been tapped?
138+
139+
By default, `SlideAction` and `IconSlideAction` close on tap.
140+
To prevent this, you can set `false` to the `closeOnTap` constructor argument.
141+
142+
#### How to prevent my Slidable to close after my list scrolled?
143+
144+
By default, a `Slidable` closes when the nearest `Scrollable` widget starts to scroll.
145+
To prevent this, you can set `false` to the `closeOnScroll` constructor argument.
146+
136147
## Changelog
137148

138149
Please see the [Changelog](https://github.com/letsar/flutter_slidable/blob/master/CHANGELOG.md) page to know what's recently changed.

lib/src/widgets/slidable.dart

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ const double _kActionsExtentRatio = 0.25;
55
const double _kFastThreshold = 2500.0;
66

77
/// Signature for the builder callback used to create slide actions.
8-
typedef Widget SlideActionBuilder(BuildContext context, int index, Animation<double> animation);
8+
typedef Widget SlideActionBuilder(
9+
BuildContext context, int index, Animation<double> animation);
910

1011
/// A delegate that supplies slide actions.
1112
///
@@ -62,7 +63,8 @@ class SlideActionBuilderDelegate extends SlideActionDelegate {
6263
final int actionCount;
6364

6465
@override
65-
Widget build(BuildContext context, int index, Animation<double> animation) => builder(context, index, animation);
66+
Widget build(BuildContext context, int index, Animation<double> animation) =>
67+
builder(context, index, animation);
6668
}
6769

6870
/// A delegate that supplies slide actions using an explicit list.
@@ -91,7 +93,8 @@ class SlideActionListDelegate extends SlideActionDelegate {
9193
int get actionCount => actions?.length ?? 0;
9294

9395
@override
94-
Widget build(BuildContext context, int index, Animation<double> animation) => actions[index];
96+
Widget build(BuildContext context, int index, Animation<double> animation) =>
97+
actions[index];
9598
}
9699

97100
/// A handle to various properties useful while calling [SlidableDelegate.buildActions].
@@ -111,7 +114,8 @@ class SlidableDelegateContext {
111114
final Slidable slidable;
112115

113116
/// The current actions that have to be shown.
114-
SlideActionDelegate get actionDelegate => showActions ? slidable.actionDelegate : slidable.secondaryActionDelegate;
117+
SlideActionDelegate get actionDelegate =>
118+
showActions ? slidable.actionDelegate : slidable.secondaryActionDelegate;
115119

116120
bool get directionIsXAxis => slidable.direction == Axis.horizontal;
117121

@@ -129,7 +133,8 @@ class SlidableDelegateContext {
129133

130134
/// Builds the slide actions using the active [SlideActionDelegate]'s builder.
131135
List<Widget> buildActions(BuildContext context) {
132-
return List.generate(actionCount, (int index) => actionDelegate.build(context, index, controller.view));
136+
return List.generate(actionCount,
137+
(int index) => actionDelegate.build(context, index, controller.view));
133138
}
134139

135140
Offset createOffset(double value) {
@@ -176,7 +181,8 @@ abstract class SlidableDelegate {
176181
const SlidableDelegate({
177182
double fastThreshold,
178183
}) : fastThreshold = fastThreshold ?? _kFastThreshold,
179-
assert(fastThreshold == null || fastThreshold >= .0, 'fastThreshold must be positive');
184+
assert(fastThreshold == null || fastThreshold >= .0,
185+
'fastThreshold must be positive');
180186

181187
/// The threshold used to know if a movement was fast and request to open/close the actions.
182188
final double fastThreshold;
@@ -243,10 +249,14 @@ class SlidableStrechDelegate extends SlidableStackDelegate {
243249
children: <Widget>[
244250
ctx.createPositioned(
245251
position: 0.0,
246-
extent: ctx.getMaxExtent(constraints) * ctx.getAnimationValue(animation).abs(),
252+
extent: ctx.getMaxExtent(constraints) *
253+
ctx.getAnimationValue(animation).abs(),
247254
child: new Flex(
248255
direction: ctx.slidable.direction,
249-
children: ctx.buildActions(context).map((a) => Expanded(child: a)).toList(),
256+
children: ctx
257+
.buildActions(context)
258+
.map((a) => Expanded(child: a))
259+
.toList(),
250260
),
251261
),
252262
],
@@ -276,7 +286,10 @@ class SlidableBehindDelegate extends SlidableStackDelegate {
276286
extent: ctx.getMaxExtent(constraints) * ctx.totalActionsExtent,
277287
child: new Flex(
278288
direction: ctx.slidable.direction,
279-
children: ctx.buildActions(context).map((a) => Expanded(child: a)).toList(),
289+
children: ctx
290+
.buildActions(context)
291+
.map((a) => Expanded(child: a))
292+
.toList(),
280293
),
281294
),
282295
],
@@ -298,7 +311,8 @@ class SlidableScrollDelegate extends SlidableStackDelegate {
298311
Widget buildStackActions(BuildContext context, SlidableDelegateContext ctx) {
299312
return new Positioned.fill(
300313
child: new LayoutBuilder(builder: (context, constraints) {
301-
final double totalExtent = ctx.getMaxExtent(constraints) * ctx.totalActionsExtent;
314+
final double totalExtent =
315+
ctx.getMaxExtent(constraints) * ctx.totalActionsExtent;
302316

303317
final animation = new Tween(
304318
begin: ctx.createOffset(-totalExtent),
@@ -315,7 +329,10 @@ class SlidableScrollDelegate extends SlidableStackDelegate {
315329
extent: totalExtent,
316330
child: new Flex(
317331
direction: ctx.slidable.direction,
318-
children: ctx.buildActions(context).map((a) => Expanded(child: a)).toList(),
332+
children: ctx
333+
.buildActions(context)
334+
.map((a) => Expanded(child: a))
335+
.toList(),
319336
),
320337
),
321338
],
@@ -339,7 +356,8 @@ class SlidableDrawerDelegate extends SlidableStackDelegate {
339356
return new Positioned.fill(
340357
child: new LayoutBuilder(builder: (context, constraints) {
341358
final count = ctx.actionCount;
342-
final double actionExtent = ctx.getMaxExtent(constraints) * ctx.slidable.actionExtentRatio;
359+
final double actionExtent =
360+
ctx.getMaxExtent(constraints) * ctx.slidable.actionExtentRatio;
343361

344362
final animations = Iterable.generate(count).map((index) {
345363
return new Tween(
@@ -354,11 +372,13 @@ class SlidableDrawerDelegate extends SlidableStackDelegate {
354372
return new Stack(
355373
children: List.generate(ctx.actionCount, (index) {
356374
// For the main actions we have to reverse the order if we want the last item at the bottom of the stack.
357-
int displayIndex = ctx.showActions ? ctx.actionCount - index - 1 : index;
375+
int displayIndex =
376+
ctx.showActions ? ctx.actionCount - index - 1 : index;
358377
return ctx.createPositioned(
359378
position: ctx.getAnimationValue(animations[index]),
360379
extent: actionExtent,
361-
child: ctx.actionDelegate.build(context, displayIndex, ctx.controller.view),
380+
child: ctx.actionDelegate
381+
.build(context, displayIndex, ctx.controller.view),
362382
);
363383
}),
364384
);
@@ -398,7 +418,8 @@ class Slidable extends StatefulWidget {
398418
child: child,
399419
delegate: delegate,
400420
actionDelegate: new SlideActionListDelegate(actions: actions),
401-
secondaryActionDelegate: new SlideActionListDelegate(actions: secondaryActions),
421+
secondaryActionDelegate:
422+
new SlideActionListDelegate(actions: secondaryActions),
402423
showAllActionsThreshold: showAllActionsThreshold,
403424
actionExtentRatio: actionExtentRatio,
404425
movementDuration: movementDuration,
@@ -426,9 +447,16 @@ class Slidable extends StatefulWidget {
426447
this.closeOnScroll = true,
427448
}) : assert(delegate != null),
428449
assert(direction != null),
429-
assert(showAllActionsThreshold != null && showAllActionsThreshold >= .0 && showAllActionsThreshold <= 1.0,
450+
assert(
451+
showAllActionsThreshold != null &&
452+
showAllActionsThreshold >= .0 &&
453+
showAllActionsThreshold <= 1.0,
430454
'showAllActionsThreshold must be between 0.0 and 1.0'),
431-
assert(actionExtentRatio != null && actionExtentRatio >= .0 && actionExtentRatio <= 1.0, 'actionExtentRatio must be between 0.0 and 1.0'),
455+
assert(
456+
actionExtentRatio != null &&
457+
actionExtentRatio >= .0 &&
458+
actionExtentRatio <= 1.0,
459+
'actionExtentRatio must be between 0.0 and 1.0'),
432460
assert(closeOnScroll != null),
433461
super(key: key);
434462

@@ -476,11 +504,14 @@ class Slidable extends StatefulWidget {
476504
SlidableState createState() => SlidableState();
477505
}
478506

479-
class SlidableState extends State<Slidable> with TickerProviderStateMixin, AutomaticKeepAliveClientMixin<Slidable> {
507+
class SlidableState extends State<Slidable>
508+
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin<Slidable> {
480509
@override
481510
void initState() {
482511
super.initState();
483-
_controller = new AnimationController(duration: widget.movementDuration, vsync: this)..addStatusListener(_handleShowAllActionsStatusChanged);
512+
_controller =
513+
new AnimationController(duration: widget.movementDuration, vsync: this)
514+
..addStatusListener(_handleShowAllActionsStatusChanged);
484515
}
485516

486517
AnimationController _controller;
@@ -494,17 +525,22 @@ class SlidableState extends State<Slidable> with TickerProviderStateMixin, Autom
494525
}
495526

496527
@override
497-
bool get wantKeepAlive => _controller != null && (_controller.isAnimating || _controller.isCompleted);
528+
bool get wantKeepAlive =>
529+
_controller != null &&
530+
(_controller.isAnimating || _controller.isCompleted);
498531

499532
/// The current actions that have to be shown.
500-
SlideActionDelegate get actionDelegate => _showActions ? widget.actionDelegate : widget.secondaryActionDelegate;
533+
SlideActionDelegate get actionDelegate =>
534+
_showActions ? widget.actionDelegate : widget.secondaryActionDelegate;
501535

502536
bool get _directionIsXAxis {
503537
return widget.direction == Axis.horizontal;
504538
}
505539

506540
double get _overallDragAxisExtent {
507-
return (_directionIsXAxis ? context.size.width : context.size.height) * widget.actionExtentRatio * (actionDelegate?.actionCount ?? 0);
541+
return (_directionIsXAxis ? context.size.width : context.size.height) *
542+
widget.actionExtentRatio *
543+
(actionDelegate?.actionCount ?? 0);
508544
}
509545

510546
@override
@@ -527,7 +563,8 @@ class SlidableState extends State<Slidable> with TickerProviderStateMixin, Autom
527563
void _addScrollingNotifierListener() {
528564
if (widget.closeOnScroll) {
529565
_scrollPosition = Scrollable.of(context)?.position;
530-
if (_scrollPosition != null) _scrollPosition.isScrollingNotifier.addListener(_isScrollingListener);
566+
if (_scrollPosition != null)
567+
_scrollPosition.isScrollingNotifier.addListener(_isScrollingListener);
531568
}
532569
}
533570

@@ -580,7 +617,8 @@ class SlidableState extends State<Slidable> with TickerProviderStateMixin, Autom
580617
final double velocity = details.primaryVelocity;
581618
final bool shouldOpen = velocity.sign == _dragExtent.sign;
582619
final bool fast = velocity.abs() > widget.delegate.fastThreshold;
583-
if (_controller.value >= widget.showAllActionsThreshold || (shouldOpen && fast)) {
620+
if (_controller.value >= widget.showAllActionsThreshold ||
621+
(shouldOpen && fast)) {
584622
open();
585623
} else {
586624
close();
@@ -599,15 +637,21 @@ class SlidableState extends State<Slidable> with TickerProviderStateMixin, Autom
599637
Widget build(BuildContext context) {
600638
super.build(context); // See AutomaticKeepAliveClientMixin.
601639

602-
if ((widget.actionDelegate == null || widget.actionDelegate.actionCount == 0) &&
603-
(widget.secondaryActionDelegate == null || widget.secondaryActionDelegate.actionCount == 0)) {
640+
if ((widget.actionDelegate == null ||
641+
widget.actionDelegate.actionCount == 0) &&
642+
(widget.secondaryActionDelegate == null ||
643+
widget.secondaryActionDelegate.actionCount == 0)) {
604644
return widget.child;
605645
}
606646

607647
Widget content = widget.child;
608648

609-
if (_showActions && widget.actionDelegate != null && widget.actionDelegate.actionCount > 0 ||
610-
!_showActions && widget.secondaryActionDelegate != null && widget.secondaryActionDelegate.actionCount > 0) {
649+
if (_showActions &&
650+
widget.actionDelegate != null &&
651+
widget.actionDelegate.actionCount > 0 ||
652+
!_showActions &&
653+
widget.secondaryActionDelegate != null &&
654+
widget.secondaryActionDelegate.actionCount > 0) {
611655
content = widget.delegate.buildActions(
612656
context,
613657
new SlidableDelegateContext(

lib/src/widgets/slide_action.dart

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ const bool _kCloseOnTap = true;
66

77
/// Abstract class for slide actions that can close after [onTap] occurred.
88
abstract class ClosableSlideAction extends StatelessWidget {
9-
/// Creates a slide that closes when a tap has occurred if [closeOnTap] is [true].
9+
/// Creates a slide that closes when a tap has occurred if [closeOnTap]
10+
/// is [true].
1011
///
1112
/// The [closeOnTap] argument must not be null.
1213
const ClosableSlideAction({
@@ -24,7 +25,8 @@ abstract class ClosableSlideAction extends StatelessWidget {
2425
/// Defaults to true.
2526
final bool closeOnTap;
2627

27-
/// Calls [onTap] if not null and closes the closest [Slidable] that encloses the given context.
28+
/// Calls [onTap] if not null and closes the closest [Slidable]
29+
/// that encloses the given context.
2830
void _handleCloseAfterTap(BuildContext context) {
2931
if (onTap != null) {
3032
onTap();
@@ -68,7 +70,8 @@ class SlideAction extends ClosableSlideAction {
6870
color == null || decoration == null,
6971
'Cannot provide both a color and a decoration\n'
7072
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'),
71-
decoration = decoration ?? (color != null ? new BoxDecoration(color: color) : null),
73+
decoration = decoration ??
74+
(color != null ? new BoxDecoration(color: color) : null),
7275
super(
7376
key: key,
7477
onTap: onTap,
@@ -121,11 +124,18 @@ class IconSlideAction extends ClosableSlideAction {
121124

122125
@override
123126
Widget buildAction(BuildContext context) {
124-
final Color foregroundColor = ThemeData.estimateBrightnessForColor(color) == Brightness.light ? Colors.black : Colors.white;
127+
final Color foregroundColor =
128+
ThemeData.estimateBrightnessForColor(color) == Brightness.light
129+
? Colors.black
130+
: Colors.white;
125131
final Text textWidget = new Text(
126132
caption ?? '',
127133
overflow: TextOverflow.ellipsis,
128-
style: Theme.of(context).primaryTextTheme.caption.copyWith(color: foregroundColor),
134+
style: Theme
135+
.of(context)
136+
.primaryTextTheme
137+
.caption
138+
.copyWith(color: foregroundColor),
129139
);
130140
return Container(
131141
color: color,

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: flutter_slidable
22
description: A Flutter implementation of slidable list item with directional slide actions.
3-
version: 0.2.0
3+
version: 0.3.0
44
author: Romain Rastel <[email protected]>
55
homepage: https://github.com/letsar/flutter_slidable
66

0 commit comments

Comments
 (0)