Skip to content

Commit

Permalink
Add documentation and some features
Browse files Browse the repository at this point in the history
  • Loading branch information
letsar committed Oct 6, 2019
1 parent ca0376c commit a563a88
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 74 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.5.4
### Added
* Ripple effect when tapping on the IconSlideAction (https://github.com/letsar/flutter_slidable/pull/89)
* Option to make the widget non-dismissible by dragging (https://github.com/letsar/flutter_slidable/pull/101)

## 0.5.3
### Fixed
* Fix SlidableDrawerActionPane when different than 2 actions (https://github.com/letsar/flutter_slidable/pull/74).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ In the `pubspec.yaml` of your flutter project, add the following dependency:
```yaml
dependencies:
...
flutter_slidable: "^0.5.3"
flutter_slidable: "^0.5.4"
```
In your library add the following import:
Expand Down
15 changes: 10 additions & 5 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ class _MyHomePageState extends State<MyHomePage> {
final List<_HomeItem> items = List.generate(
20,
(i) => _HomeItem(
i,
'Tile n°$i',
_getSubtitle(i),
_getAvatarColor(i),
),
i,
'Tile n°$i',
_getSubtitle(i),
_getAvatarColor(i),
),
);

@protected
Expand Down Expand Up @@ -148,6 +148,11 @@ class _MyHomePageState extends State<MyHomePage> {
),
],
secondaryActions: <Widget>[
Container(
height: 800,
color: Colors.green,
child: Text('a'),
),
IconSlideAction(
caption: 'More',
color: Colors.grey.shade200,
Expand Down
23 changes: 23 additions & 0 deletions lib/src/widgets/fractionnally_aligned_sized_box.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import 'package:flutter/widgets.dart';

/// A widget that positions its child to a fraction of the total available space.
class FractionallyAlignedSizedBox extends StatelessWidget {
/// Creates a widget that positions its child to a fraction of the total available space.
///
/// Only two out of the three horizontal values ([leftFactor], [rightFactor],
/// [widthFactor]), and only two out of the three vertical values ([topFactor],
/// [bottomFactor], [heightFactor]), can be set. In each case, at least one of
/// the three must be null.
///
/// If non-null, the [widthFactor] and [heightFactor] arguments must be
/// non-negative.
FractionallyAlignedSizedBox({
Key key,
@required this.child,
Expand All @@ -18,12 +28,25 @@ class FractionallyAlignedSizedBox extends StatelessWidget {
assert(heightFactor == null || heightFactor >= 0.0),
super(key: key);

/// The relative distance that the child's left edge is inset from the left of the parent.
final double leftFactor;

/// The relative distance that the child's top edge is inset from the top of the parent.
final double topFactor;

/// The relative distance that the child's right edge is inset from the right of the parent.
final double rightFactor;

/// The relative distance that the child's bottom edge is inset from the bottom of the parent.
final double bottomFactor;

/// The child's width relative to its parent's width.
final double widthFactor;

/// The child's height relative to its parent's height.
final double heightFactor;

/// The widget below this widget in the tree.
final Widget child;

@override
Expand Down
70 changes: 61 additions & 9 deletions lib/src/widgets/slidable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class SlideActionListDelegate extends SlideActionDelegate {
/// The slide actions.
final List<Widget> actions;

/// The number of actions.
@override
int get actionCount => actions?.length ?? 0;

Expand All @@ -156,6 +157,7 @@ class _SlidableScope extends InheritedWidget {
bool updateShouldNotify(_SlidableScope oldWidget) => oldWidget.state != state;
}

/// The data used by a [Slidable].
class SlidableData extends InheritedWidget {
SlidableData({
Key key,
Expand All @@ -174,17 +176,35 @@ class SlidableData extends InheritedWidget {
@required Widget child,
}) : super(key: key, child: child);

/// The type of slide action that is currently been showed by the [Slidable].
final SlideActionType actionType;

/// The rendering mode in which the [Slidable] is.
final SlidableRenderingMode renderingMode;

/// The total extent of all the actions
final double totalActionsExtent;

/// The offset threshold the item has to be dragged in order to be considered
/// dismissed.
final double dismissThreshold;

/// Indicates whether the [Slidable] can be dismissed.
final bool dismissible;

/// The current actions that have to be shown.
final SlideActionDelegate actionDelegate;

/// Animation for the whole movement.
final Animation<double> overallMoveAnimation;

/// Animation for the actions.
final Animation<double> actionsMoveAnimation;

/// Dismiss animation.
final Animation<double> dismissAnimation;

/// The slidable.
final Slidable slidable;

/// Relative ratio between one slide action and the extent of the child.
Expand All @@ -193,16 +213,31 @@ class SlidableData extends InheritedWidget {
/// The direction in which this widget can be slid.
final Axis direction;

/// Indicates whether the primary actions are currently shown.
bool get showActions => actionType == SlideActionType.primary;

/// The number of actions.
int get actionCount => actionDelegate?.actionCount ?? 0;

/// If the [actionType] is [SlideActionType.primary] returns 1, -1 otherwise.
double get actionSign => actionType == SlideActionType.primary ? 1.0 : -1.0;

/// Indicates wheter the direction is horizontal.
bool get directionIsXAxis => direction == Axis.horizontal;

/// The alignment of the actions.
Alignment get alignment => Alignment(
directionIsXAxis ? -actionSign : 0.0,
directionIsXAxis ? 0.0 : -actionSign,
);

/// If the [direction] is horizontal, returns the [totalActionsExtent]
/// otherwise null.
double get actionPaneWidthFactor =>
directionIsXAxis ? totalActionsExtent : null;

/// If the [direction] is vertical, returns the [totalActionsExtent]
/// otherwise null.
double get actionPaneHeightFactor =>
directionIsXAxis ? null : totalActionsExtent;

Expand Down Expand Up @@ -238,6 +273,7 @@ class SlidableData extends InheritedWidget {
);
}

/// Creates a [FractionallyAlignedSizedBox] related to the current direction and showed actions.
FractionallyAlignedSizedBox createFractionallyAlignedSizedBox({
Widget child,
double extentFactor,
Expand All @@ -262,14 +298,16 @@ class SlidableData extends InheritedWidget {
return List.generate(
actionCount,
(int index) => actionDelegate.build(
context,
index,
actionsMoveAnimation,
SlidableRenderingMode.slide,
),
context,
index,
actionsMoveAnimation,
SlidableRenderingMode.slide,
),
);
}

/// Whether the framework should notify widgets that inherit from this widget.
@override
bool updateShouldNotify(SlidableData oldWidget) =>
(oldWidget.actionType != actionType) ||
(oldWidget.renderingMode != renderingMode) ||
Expand All @@ -288,19 +326,29 @@ class SlidableData extends InheritedWidget {
/// A controller that keep tracks of the active [SlidableState] and close
/// the previous one.
class SlidableController {
/// Creates a controller that keep tracks of the active [SlidableState] and close
/// the previous one.
SlidableController({
this.onSlideAnimationChanged,
this.onSlideIsOpenChanged,
});

/// Function called when the animation changed.
final ValueChanged<Animation<double>> onSlideAnimationChanged;

/// Function called when the [Slidable] open status changed.
final ValueChanged<bool> onSlideIsOpenChanged;

bool _isSlideOpen;

Animation<double> _slideAnimation;

SlidableState _activeState;

/// The state of the active [Slidable].
SlidableState get activeState => _activeState;

/// Changes the state of the active [Slidable].
set activeState(SlidableState value) {
_activeState?._flingAnimationController();

Expand Down Expand Up @@ -559,8 +607,11 @@ class SlidableState extends State<Slidable>
double get _totalActionsExtent => widget.actionExtentRatio * (_actionCount);

double get _dismissThreshold {
if (widget.dismissal == null) return _kDismissThreshold;
else return widget.dismissal.dismissThresholds[actionType] ?? _kDismissThreshold;
if (widget.dismissal == null)
return _kDismissThreshold;
else
return widget.dismissal.dismissThresholds[actionType] ??
_kDismissThreshold;
}

bool get _dismissible => widget.dismissal != null && _dismissThreshold < 1.0;
Expand Down Expand Up @@ -716,8 +767,9 @@ class SlidableState extends State<Slidable>
if (_dismissible && !widget.dismissal.dragDismissible) {
// If the widget is not dismissible by dragging, clamp drag result
// so the widget doesn't slide past [_totalActionsExtent].
_overallMoveController.value = (_dragExtent.abs() / _overallDragAxisExtent)
.clamp(0.0, _totalActionsExtent);
_overallMoveController.value =
(_dragExtent.abs() / _overallDragAxisExtent)
.clamp(0.0, _totalActionsExtent);
} else {
_overallMoveController.value =
_dragExtent.abs() / _overallDragAxisExtent;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/widgets/slidable_action_pane.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class SlidableBehindActionPane extends StatelessWidget {

/// An action pane that creates actions which follow the item while it's sliding.
class SlidableScrollActionPane extends StatelessWidget {
/// Creates an action pane that creates actions which follow the item while it's sliding.
const SlidableScrollActionPane({Key key}) : super(key: key);

@override
Expand Down Expand Up @@ -139,6 +140,7 @@ class SlidableScrollActionPane extends StatelessWidget {

/// An action pane that creates actions which animate like drawers while the item is sliding.
class SlidableDrawerActionPane extends StatelessWidget {
/// Creates an action pane that creates actions which animate like drawers while the item is sliding.
const SlidableDrawerActionPane({Key key}) : super(key: key);

@override
Expand Down
62 changes: 6 additions & 56 deletions lib/src/widgets/slidable_dismissal.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_slidable/src/widgets/fractionnally_aligned_sized_box.dart';
import 'package:flutter_slidable/src/widgets/slidable.dart';

const Duration _kResizeDuration = const Duration(milliseconds: 300);

/// A wiget that controls how the [Slidable] is dismissed.
/// A widget that controls how the [Slidable] is dismissed.
///
/// The [Slidable] widget calls the [onDismissed] callback either after its size has
/// collapsed to zero (if [resizeDuration] is non-null) or immediately after
Expand All @@ -17,6 +16,7 @@ const Duration _kResizeDuration = const Duration(milliseconds: 300);
/// * [SlidableDrawerDismissal], which creates slide actions that are displayed like drawers
/// while the item is dismissing.
class SlidableDismissal extends StatelessWidget {
/// Creates a widget that controls how the [Slidable] is dismissed.
const SlidableDismissal({
@required this.child,
this.dismissThresholds = const <SlideActionType, double>{},
Expand Down Expand Up @@ -84,6 +84,7 @@ class SlidableDismissal extends StatelessWidget {
/// The widget to show when the [Slidable] enters dismiss mode.
final Widget child;

@override
Widget build(BuildContext context) {
final SlidableData data = SlidableData.of(context);

Expand All @@ -105,8 +106,11 @@ class SlidableDismissal extends StatelessWidget {
/// while the item is dismissing.
/// The further slide action will grow faster than the other ones.
class SlidableDrawerDismissal extends StatelessWidget {
/// Creates a specific dismissal that creates slide actions that are displayed like drawers
/// while the item is dismissing.
const SlidableDrawerDismissal({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
final SlidableData data = SlidableData.of(context);

Expand Down Expand Up @@ -151,61 +155,7 @@ class SlidableDrawerDismissal extends StatelessWidget {
}),
),
);
// return Stack(
// children: List.generate(data.actionCount, (index) {
// // For the main actions we have to reverse the order if we want the last item at the bottom of the stack.
// int displayIndex =
// data.showActions ? data.actionCount - index - 1 : index;

// return data.createFractionallyAlignedSizedBox(
// positionFactor:
// data.actionExtentRatio * (data.actionCount - index - 1),
// extentFactor: extentAnimations[index].value,
// child: data.actionDelegate.build(context, displayIndex,
// data.actionsMoveAnimation, data.renderingMode),
// );
// }),
// );
}),
// Positioned.fill(
// child: LayoutBuilder(builder: (context, constraints) {
// final count = data.actionCount;
// final double totalExtent = data.getMaxExtent(constraints);
// final double actionExtent = totalExtent * data.actionExtentRatio;

// final extentAnimations = Iterable.generate(count).map((index) {
// return Tween<double>(
// begin: actionExtent,
// end: totalExtent -
// (actionExtent * (data.actionCount - index - 1)),
// ).animate(
// CurvedAnimation(
// parent: data.overallMoveAnimation,
// curve: Interval(data.totalActionsExtent, 1.0),
// ),
// );
// }).toList();

// return AnimatedBuilder(
// animation: data.overallMoveAnimation,
// builder: (context, child) {
// return Stack(
// children: List.generate(data.actionCount, (index) {
// // For the main actions we have to reverse the order if we want the last item at the bottom of the stack.
// int displayIndex = data.showActions
// ? data.actionCount - index - 1
// : index;
// return data.createPositioned(
// position: actionExtent * (data.actionCount - index - 1),
// extent: extentAnimations[index].value,
// child: data.actionDelegate.build(context, displayIndex,
// data.actionsMoveAnimation, data.renderingMode),
// );
// }),
// );
// });
// }),
// ),
SlideTransition(
position: animation,
child: data.slidable.child,
Expand Down
Loading

0 comments on commit a563a88

Please sign in to comment.