AdvStory Docs
Comment on page

Creating Custom Trays

This page contains information about creating animated and non-animated custom story trays.

Non-animated Custom Tray

Any widget can be used as a tray in AdvStory, this is entirely up to the developer.
trayBuilder: (int index) {
return MyNonAnimatedTray(index);
This is an example of non-animated custom tray from example project.

Animated Custom Tray

Tray animation runs when stories are building, media files are loading and preparing to display. If AdvStoryTray doesn't suit your needs, you can create your own animated tray by following some rules.
Instead of showing a loading screen after the story screen opens, it shows an animation to your users. This provides better experience.
  • Animated trays should be StatefulWidget and widget class should extend AnimatedTray class.
  • State class should extend AnimatedTrayState class. This class listens a variable from an inherited widget and starts/stops animation under the hood.
When you return a class that extends AnimatedTray from trayBuilder, AdvStory handles it's animation automatically, no need any extra parameter. You need to override startAnimation and stopAnimation methods inside of state class, this way, AdvStory can start and stop your animation as needed.
// Extend AnimatedTray class
class MyAnimatedTray extends AnimatedTray {
const MyAnimatedTray({Key? key}) : super(key: key);
AnimatedTrayState<MyAnimatedTray> createState() => CustomAnimatedTrayState();
// Extend AnimatedTrayState class
class MyAnimatedTrayState extends AnimatedTrayState<MyAnimatedTray>
with TickerProviderStateMixin{
late final _controller = AnimationController(vsync: this);
// This function called every time the tray need to animate.
void startAnimation() {
_controller.repeat(reverse: true);
// This function called when the tray need to stop animation.
void stopAnimation() {
Widget build(BuildContext context) {
return Container(
You can see source code from here​