Flutter: timing the display of widgets

Francesco Mineo
Flutter Community
Published in
4 min readJan 25, 2019

--

In this article, I’d like to show you one of my experiments with Flutter: The StagedObject (and its derived widget StagedWidget).

What is it?

I had an idea, what if we could set a list of widgets (and even pages) and relative timing to display them? I am not talking about animations, I am talking about different widgets, even pages, shown at a given time. Think of it as a presentation or maybe an app where you want to show its features in a sort of demo mode.

This is a trivial example, just to show what I mean.

“Flutter is limitless! Period.” (better gif here)

From this idea I made the StagedObject :

The Stage class holds the setting of the stage: the widget/page to display, the time (both absolute or relative timing), and the onShow callback used to call a function when the stage shows.

Basically, the StageObject takes a Map<int, Stage> and plays every stage. It is possible to set the type of timing by setting the absoluteTiming flag (to tell the StagedObject if the time property indicates when to display the widget or how much it should last).

The onStart callback is called when the timer starts, while the onEnd is fired at the end of the last Stage (if on relativeTiming, so absoluteTiming is set to false), for example, to pop the page at the end of the last stage.

How to use it?

From the StagedObject example:

  1. Declare a map <int, Stage>

Here the map is in the view and it is passed to the StagedObject declared in the BLoC class by the setStagesMap method.

Map<int, Stage> get stagesMap => <int, Stage>{
0: Stage(
widget: Container(
width: 200.0,
height: 200.0,
color: Colors.indigo[200],
alignment: Alignment.center,
key: Key(‘0’),
child: ScrollingText(
text: ‘This stage will last 8 seconds. By the onShow call back it is possibile to assign an action when the widget shows.’,
scrollingDuration: 2000,
style: TextStyle(
color: Colors.blue,
fontSize: 18.0,
fontWeight: FontWeight.w500)),
),
time: 8000,
onShow: () {}
),
1: Stage(
widget: Container(
width: 200.0,
height: 200.0,
color: Colors.indigo[200],
alignment: Alignment.center,
key: Key(‘1’),
child: ScrollingText(
text: ‘The next widgets will cross fade.’,
scrollingDuration: 2000,
),
),
time: 8000,
onShow: () {}
),
}

2. In the BLoC

final text = StreamedValue<String>();
final staged = StagedObject();
// The map can be set through the constructor of the StagedObject
// or by the setStagesMap method like in this case.
setMap(Map<int, Stage> stagesMap) {
staged.setStagesMap(stagesMap);
}
// This method is then called from a button in the view
start() {
if (staged.getMapLength() > 0) {
staged.setCallback(sendNextStageText);
staged.startStages();
}
}
// By this method we get the next stage to show it
// in a little box below the current stage
sendNextStageText() {
var nextStage = staged.getNextStage();
if (nextStage != null) {
text.value = “Next stage:”;
widget.value = nextStage.widget;
stage.value = StageBridge(
staged.getStageIndex(), staged.getCurrentStage(), nextStage);
} else {
text.value = “This is the last stage”;
widget.value = Container();
}
}

3. In the view:

// Setting the map in the build method
StagedObjectBloc bloc = BlocProvider.of(context);
bloc.setMap(stagesMap);
// To show the current widget on the view using the ReceiverWidget.
// As an alternative it can be used the
// StreamedWidget/StreamBuilder.
ReceiverWidget(
stream: bloc.staged.widgetStream,
),

N.B. you can call the bloc.start() method for example from a button and start displaying the stages.

StagedWidget

To make the things easier, I created a specific widget driven by a StagedObject. It takes as a parameter just a map with the stages, the type of timing (by default is set to relative), and the callbacks onStart and onEnd.

It is useful when you just need to play the stages when the page shows till the last one, and don’t need to play, pause or reset the stage. In that case, it is necessary to use a StagedObject and drive it by its methods.

This is the source code of the gif shown at the beginning of the article:

Conclusion

I hope this could be useful. You can find the source code both of the library and the examples here in my GitHub repository. The library is still a work in progress.

UPDATE: package released.

--

--

Francesco Mineo
Flutter Community

Medical doctor, singer & music producer , software developer.