stacker 0.1.0 copy "stacker: ^0.1.0" to clipboard
stacker: ^0.1.0 copied to clipboard

A collection of 3 widgets that stack their children, displaying a single child at a time, transitioning between children when a different child is displayed. Stacker can be used modularly as a compone [...]

stacker #

A collection of 3 widgets that stack their children, displaying a single child at a time, transitioning between children when a different child is displayed.

Stacker can be used modularly as a component, to drive single-page apps, or to control multi-step flows within a widget or page.

Usage #

import 'package:stacker/stacker.dart';

StackSwapper #

[StackSwapper] is the simplest of the three widgets. It accepts a single child and implicity transitions to displaying a new child when its child is updated.

/// The child being displayed by the [StackSwapper].
var child = Container(child: Text('A'));

/// Transitions [StackSwapper] to displaying a different widget.
void updateChild() {
  child = Container(child: Text('B'));
  setState(() {});
}

/// Build the [StackSwapper].
@override
Widget build(BuildContext context) {
  return StackSwapper(child);
}

StackSwitcher #

[StackSwitcher] accepts a list of children and the index of the child that should be displayed. When the index is changed it will transition to displaying the child at the new index.

/// The children contained in [StackSwitcher]'s stack.
final children = <Widget>[
  Container(child: Text('A')),
  Container(child: Text('B')),
  Container(child: Text('C')),
  Container(child: Text('D')),
  Container(child: Text('E')),
];

/// The index of the child in [children] currently being
/// dispalyed by the [StackSwitcher].
var currentChild = 0;

/// Transitions [StackSwitcher] to displaying the next child in the list.
void nextChild() {
  currentChild = (currentChild + 1) % children.length;
  setState(() {});
}

/// Build the [StackSwitcher].
@override
Widget build(BuildContext context) {
  return StackSwitcher(children, child: currentChild);
}

Maintaining States #

The states of every child in the stack can be maintained when they're not visible by setting the [maintainStates], [maintainAnimations], or [maintainSizes] parameters to true.

[maintainStates] will maintain the state of the child.

[maintainAnimations] will keep the animation ticker providers active while the children are hidden. Setting this to true will automatically set [maintainStates] to true.

[maintainSizes] will maintain the space the hidden children would occupy if they were visible. Setting this to true will automatically set [maintainAnimations] and [maintainStates] to true.

/// A [StackSwitcher] where every child's state will
/// be maintained when they're hidden.
StackSwitcher(
  children,
  child: currentChild,
  maintainStates: true,
);

An individual child's state/animation/size can be maintained by wrapping the child in a [MaintainState] widget.

[MaintainState] has 2 parameters, [maintainAnimation] and [maintainSize]. Setting [maintainSize] to true will automatically set [maintainAnimation] to true.

/// A list of children whose states will be maintained, or not,
/// independently of one another.
final children = <Widget>[
  // The state of this widget will be maintained when it is hidden.
  MaintainState(MyStatefulWidget())),

  // The state of this child will not be maintained when it is hidden.
  MyStatefulWidget(),

  // The state and animation tickers of this widget will be
  // maintained when it is hidden.
  MaintainState(
    MyStatefulWidget(),
    maintainAnimation: true,
  ),

  // The state of this child will not be maintained when it is hidden.
  MyStatefulWidget(),

  // The state, animation tickers, and size of this widget will be
  // maintained when it is hidden.
  MaintainState(
    MyStatefulWidget(),
    maintainSize: true,
  ),
];

Stacker #

[Stacker] accepts a single child, which acts as the root of a linear history of widgets, which can be navigated (like a browser's back and forward buttons.)

New children can be built, inserted into, or removed from the stack on the fly.

There a number of direct methods for controlling and navigating the stack, which are accessed from the [Stacker]'s instance.

All of [Stacker]'s navigation/build methods have an optional [onComplete] parameter, which can be used to provide a callback that will be called a single time when the transition triggered by that method completes.

/// An instance of a [Stacker]. By storing the [Stacker] as an instance,
/// its direct methods can be used to control it.
final myStacker = Stacker(MyRootWidget());

/// Builds and transitions to a new [child].
void build(Widget child, {VoidCallback onComplete}) {
  myStacker.build(child, onComplete: onComplete);
}

/// Transitions to the child before the child currently being displayed.
void back({VoidCallback onComplete}) {
  myStacker.back(onComplete: onComplete);
}

/// Transitions to the child after the child currently being displayed.
void forward({VoidCallback onComplete}) {
  myStacker.forward(onComplete: onComplete);
}

/// Transitions to the child at [index].
void open(int index, {VoidCallback onComplete}) {
  myStacker.open(index, onComplete: onComplete);
}

/// Transitions to the child before the child currently being displayed,
/// and removing the current child and every child after it from the history.
void pop({VoidCallback onComplete}) {
  myStacker.pop(onComplete: onComplete);
}

/// Transitions to the root child.
void root({VoidCallback onComplete}) {
  myStacker.root(onComplete: onComplete);
}

Those same methods are also accessible from any of the [Stacker]'s children via a [BuildContext] extension by calling [context] within a [StatelessWidget]'s [build] method, or anywhere within a [State]. Note: These have the same optional parameters as their respective equivalent methods listed above and in the section below.

// Builds and transitions to a new child.
context.stacker.build(child);

// Transitions to the previous child.
context.stacker.back();

// Transitions to the next child.
context.stacker.forward();

// Transitions to the child at [index].
context.stacker.open(index);

// Transitions the previous child and clears the history.
context.stacker.pop();

// Transitions to the root child.
context.stacker.root();

Note: If a [Stacker] is built directly by its parent's [build] method, only its children will be able to access the methods to control the stacker, which may be all you need depending on the use-case.

/// The [Stacker] built here can only be controlled by
/// [MyRootWidget] or any other children added to it.
@override
Widget build(BuildContext context) {
  return Stacker(MyRootWidget());
}

Managing the History #

The history can be cleared by calling [clearHistory]. The history is also cleared when building or appending a widget to the history, unless the [build] or [append] methods' [clearHistory] parameter is changed to false, or when navigating to the root child by setting the [clearHistory] parameter to true.

/// Builds and transitions to a new [child], clearing the history
/// by default.
///
/// If [clearHistory] is set to `false`, every child in the forward
/// history will be pushed back when the new [child] is built.
void build(Widget child, {bool clearHistory = true}) {
  myStacker.build(child, clearHistory: clearHistory);
}

/// Transitions to the root widget in the stack, clearing the history
/// if [clearHistory] is set to `true`.
void root({bool clearHistory = false}) {
  myStacker.root(clearHistory: clearHistory);
}

Children can be inserted into or removed from the history by any of the below methods.

/// Inserts a [child] into the stack before the one currently
/// being displayed.
void prepend(Widget child) {
  myStacker.prepend(child);
}

/// Inserts a [child] into the stack after the one currently
/// being displayed, clearing the history by default.
void append(Widget child, {bool clearHistory = true}) {
  myStacker.append(child, clearHistory: clearHistory);
}

/// Inserts a [child] into the stack at [index], pushing
/// every child occuring on or after [index] back.
void insert(int index, Widget child) {
  myStacker.insert(index, child);
}

/// Removes the first instance of [child] from the stack.
void remove(Widget child) {
  myStacker.remove(child);
}

/// Removes the child from the stack at [index].
void removeAt(int index) {
  myStacker.removeAt(index);
}

/// Removes every widget from stack after the one currently
/// being diplayed, clearing the forward history.
///
/// If [skip] is `> 0`, that number of widgets after the one currently
/// being displayed will be retained in the history.
void clearHistory([int skip = 0]) {
  myStacker.clearHistory(skip);
}

All of the above methods are also accessible to a [Stacker]'s children via the [BuildContext] extension. Note: These methods have the same optional parameters as their respective equivalents listed above.

// Inserts a child into the stack before the one currently
// being displayed.
context.stacker.prepend(child);

// Inserts a child into the stack after the one currently
// being displayed, clearing the history by default.
context.stacker.append(child);

// Inserts a [child] into the stack at [index], pushing
// every child occuring on or after [index] back.
context.stacker.insert(index, child);

// Removes the first instance of [child] from the stack.
context.stacker.remove(child);

// Removes the child from the stack at [index].
context.stacker.removeAt(index);

// Removes every widget from stack after the one currently
// being diplayed
context.stacker.clearHistory();

Android Back Button #

The [backButton] parameter can be set to true to have the [Stacker] intercept the Android back button and navigate backwards in the [Stacker]'s history when it's pressed.

/// This [Stacker] can be navigated with Android's back button.
Stacker(
  MyRootWidget(),
  backButton: true,
);

If the root child is being displayed, the back button will defer to the default behavior.

Maintaining States #

A [Stacker]'s childrens' states can be maintained in the same way as a [StackSwitcher]s', either by setting the [maintainStates], [maintainAnimations], or [maintainSizes] parameters to true, or by wrapping individual children in a [MaintainState] widget.

Parameters #

Each of the widgets have a number of shared parameters used to provide callbacks or to customize their transition animation.

Transitions #

The transitions between children are handled by a FadeAndTranslate widget, which fades each child in/out while translating their positional offsets.

There are several parameters used to specify the duration, offset, and additional behavior of the transitions.

/// A [StackSwapper] built with the default parameters..
StackSwapper(
  myWidget,
  // The duration of the transition animation.
  transitionDuration: Duration(milliseconds: 240),
  // The offset the children translate to during the transition.
  transitionTranslation: Offset(0.0, -24.0),
  // If `true`, the children will translate in opposite directions,
  // if `false`, they'll translate in the same direction.
  invertTranslations: true,
  // If `true`, the first child built will transition from being hidden
  // to being visible, if `false`, it will be built as visible.
  transitionFirstChild: false,
),

Note: [StackSwitcher] and [Stacker] have the same default values for their equivalent parameters as the [STackSwapper] above.

Callbacks #

Each of the widgets also accepts two callbacks, [onSwitchStart] and [onSwitchComplete], which are called each time a transition starts and completes, respectively.

Stacker(
  myWidget,
  // A callback called every time a transition starts.
  onSwitchStart: () => print('Transition starting.'),
  // A callback called every time a transition has completed.
  onSwitchComplete: () => print('Transition completed.'),
);
1
likes
30
pub points
0%
popularity

Publisher

verified publisherjamesalex.dev

A collection of 3 widgets that stack their children, displaying a single child at a time, transitioning between children when a different child is displayed. Stacker can be used modularly as a component, to drive single-page apps, or to control multi-step flows within a widget or page.

Repository (GitHub)
View/report issues

License

BSD-2-Clause (LICENSE)

Dependencies

fade_and_translate, flutter, provider

More

Packages that depend on stacker