flutter_story 1.0.1

SDKflutter
Platformandroidioswindowslinuxmacosweb

A flutter plugin for creating story (like Instagram, WhatsApp, Telegram, Facebook, etc) for all platforms.

Story for Flutter

pub package likes GitHub Stars License points popularity Platform

A flutter plugin for creating story (like Instagram, WhatsApp, Telegram, Facebook, etc) for all platforms.

Features

  • Widget support on story (Image, Video, Text, etc).
  • Pause, play, next, previous and drag with touch and story controller.
  • Creating custom footer (with message box or custom widget), like and forward buttons.
  • Animated progress indicator for each story card.



To see example of the following Story on a device or simulator:

cd example/
flutter run --release

Demo

flutter_story flutter_story flutter_story flutter_story

flutter_story

Source Link: example/lib/main.dart


Getting Started

  1. Installation
  2. Usage
  3. Custom Usage
  4. StoryUser Usage
  5. StoryCard Usage
  6. StoryCardFooter Usage
  7. StoryCardMessageBox Usage
  8. StoryCardLikeButton Usage
  9. StoryCardForwardButton Usage
  10. Story Controller
  11. Story Builder

Installation

Add flutter_story as a dependency in your pubspec.yaml file:

dependencies:
  flutter_story: ^1.0.1

Import the plugin package to your dart code

import 'package:flutter_story/flutter_story.dart';

Usage

StoryUserStoryCard

Simple usage

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story(
        children: [
          StoryUser(
            avatar: Image.asset("assets/user_avatar.jpg"),
            label: const Text("UserName"),
            children: const [
              StoryCard(
                child: Center(
                  child: Text("This is the story card widget",
                    style: TextStyle(color: Colors.white),),
                ),
              )
            ],
          )
        ],
      ),
    ),
  );
}

Custom Usage

There are several options that allow for more control:

PropertiesData TypeDescription
controllerStoryControllerIt can be used to control the state of Story.
autoplayboolAllows autoplaying of Story. if set this to false, the Story does not play.
heightdoubleThe height of the Story.
colorColorThe color to fill the Story.
backgroundColorColorThe color to fill the backgroundColor of the Story.
paddingEdgeInsetsThe padding of the Story.
shrinkWrapboolWhether the extent of the scroll view in the scrollDirection should be determined by the contents being viewed.
physicsScrollPhysicsHow the scroll view should respond to user input.
reverseboolWhether the scroll view scrolls in the reading direction.
scrollDirectionAxisThe Axis along which the scroll view's offset increases. Defaults to Axis.horizontal.
scrollControllerScrollControllerAn object that can be used to control the position to which this scroll view is scrolled.
childrenList<StoryUser>Creates a list of the StoryUser layout widget.
itemBuilderWidgetBuilder(StoryUser)Creates a scrollable, linear array of widgets that are created on demand.
sortByVisitedboolIf set to true, The list of Story sorts by StoryCard.visited.
findChildIndexCallbackChildIndexGetterCalled to find the new index of a child based on its key in case of reordering.
itemCountboolThe itemBuilder callback will be called only with indices greater than or equal to zero and less than itemCount.
addAutomaticKeepAlivesboolWhether to wrap each child in an AutomaticKeepAlive. Typically, children in lazy list are wrapped in AutomaticKeepAlive.
addRepaintBoundariesboolWhether to wrap each child in a RepaintBoundary. Typically, children in a scrolling container are wrapped in repaint boundaries so that they do not need to be repainted as the list scrolls.
addSemanticIndexesboolWhether to wrap each child in an IndexedSemantics. Typically, children in a scrolling container must be annotated with a semantic index in order to generate the correct accessibility announcements.

StoryUser Usage

Using the StoryUser

Manually change the StoryUser properties.

PropertiesData TypeDescription
userIdintThe userId of the StoryUser.
widthdoubleThe width of the StoryUser.
heightdoubleThe height of the StoryUser.
marginEdgeInsetsThe margin of the StoryUser.
avatarColorColorThe color to fill the background of the StoryUser.avatar.
borderWidthdoubleDetermines the width of the StoryUser border.
borderColorColorDetermines the color of the StoryUser border.
visitedBorderColorColorDetermines the color of the StoryCard border, when all StoryUser child visited.
borderPaddingEdgeInsetsThe padding of the StoryUser.avatar border.
borderRadiusBorderRadiusIf non-null, the corners of StoryUser are rounded by this.
avatarWidgetThe avatar of the StoryUser. A Widget that is placed in the StoryUser.avatar.
labelTextA Text Widget that is placed in bottomCenter of the StoryUser.avatar.
childrenList<StoryCard>Creates a StoryUser layout widget. By default, the non-positioned children of the StoryUser are aligned by their top left corners.
onPressedValueChanged<int>This callback is called when pressed on the StoryUser.avatar. Returns a index of the StoryUser list.
onLongPressedValueChanged<int>This callback is called when long pressed on the StoryUser.avatar. Returns a index of the StoryUser list.

StoryCard Usage

Using the StoryCard

Manually change the StoryCard properties.

PropertiesData TypeDescription
visitedboolIf set true, the next card is displayed and all previous cards must be set true. If all are set false, they will be displayed from the first card. If all are set true, they will be displayed from the first card and its borderColor change to StoryUser.borderColor.
cardDurationDurationDetermines the time to show the StoryCard.
colorColorThe color of the StoryCard background.
borderRadiusBorderRadiusIf non-null, the corners of StoryCard are rounded by this.
progressBarHeightdoubleThe progressBarHeight of the StoryCard tab bar.
footerStoryCardFooterThe footer of the StoryCard. A Widget that is placed in bottom of the StoryCard.
childOverlayWidgetA Widget that is placed on the StoryCard.child.
childWidgetCreates a StoryCard layout widget.
onVisitedValueChanged<int>This callback is called when StoryCard is visited. Returns a card index of the StoryCard list.
onDisposeValueChanged<int>This callback is called when StoryCard is dispose. Returns a card index of the StoryCard list.
onPauseValueChanged<int>This callback is called when StoryCard is paused. Returns a card index of the StoryCard list.
onResumeValueChanged<int>This callback is called when StoryCard is played. Returns a card index of the StoryCard list.
onNextValueChanged<int>This callback is called when next StoryCard is displayed. Returns a card index of the StoryCard list.
onPreviousValueChanged<int>This callback is called when previous StoryCard is displayed. Returns a card index of the StoryCard list.

StoryCardFooter Usage

Using the StoryCardFooter

Manually change the StoryCardFooter properties.

PropertiesData TypeDescription
messageBoxStoryCardMessageBoxIf null, the child is displayed.
likeButtonStoryCardLikeButtonIf non-null, the likeButton is placed in right of the StoryCardMessageBox.
forwardButtonStoryCardForwardButtonIf non-null, the forwardButton is placed in right of the StoryCardMessageBox.
childWidgetCreates a StoryCardFooter layout widget.

StoryCardFooter

StoryCard includes footer: StoryCardFooter

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story(
        children: [
          StoryUser(
            avatar: Image.asset("assets/user_avatar.jpg"),
            label: const Text("UserName"),
            children: const [
              StoryCard(
                footer: StoryCardFooter(
                  child: Text(
                    "This is the story card footer widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
                child: Center(
                  child: Text(
                    "This is the story card widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              )
            ],
          )
        ],
      ),
    ),
  );
}

StoryCardMessageBox Usage

Using the StoryCardMessageBox

Manually change the StoryCardMessageBox properties.

PropertiesData TypeDescription
colorColorThe text color of the StoryCardMessageBox.
borderRadiusBorderRadiusIf non-null, the corners of the StoryCardMessageBox are rounded by this.
borderWidthdoubleDetermines the width of the StoryCardMessageBox border.
hintTextStringThe hintText of the StoryCardMessageBox.
fontSizedoubleThe fontSize of the StoryCardMessageBox.
childWidgetCreates a layout widget on the StoryCard when the StoryCardMessageBox.
onMessageValueChanged<StoryCardMessage>This callback is called when previous StoryCard is displayed. Returns a StoryCardMessage that includes the card index and message.

StoryCardMessageBox

StoryCardFooter includes messageBox: StoryCardMessageBox

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story(
        children: [
          StoryUser(
            avatar: Image.asset("assets/user_avatar.jpg"),
            label: const Text("UserName"),
            children: const [
              StoryCard(
                footer: StoryCardFooter(
                  messageBox: StoryCardMessageBox(),
                  likeButton: StoryCardLikeButton(),
                  forwardButton: StoryCardForwardButton(),
                ),
                child: Center(
                  child: Text(
                    "This is the story card widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              )
            ],
          )
        ],
      ),
    ),
  );
}

StoryCardMessageBoxEmojis

StoryCardMessageBox emojis

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story(
        children: [
          StoryUser(
            avatar: Image.asset("assets/user_avatar.jpg"),
            label: const Text("UserName"),
            children: [
              StoryCard(
                footer: StoryCardFooter(
                  messageBox: StoryCardMessageBox(
                    child: Center(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          MaterialButton(
                            shape: const CircleBorder(),
                            child: const Text(
                              "😂",
                              style: TextStyle(fontSize: 32),
                            ),
                            onPressed: () {},
                          ),
                          const SizedBox(width: 10),
                          MaterialButton(
                            shape: const CircleBorder(),
                            child: const Text(
                              "😂",
                              style: TextStyle(fontSize: 32),
                            ),
                            onPressed: () {},
                          ),
                          const SizedBox(width: 10),
                          MaterialButton(
                            shape: const CircleBorder(),
                            child: const Text(
                              "😂",
                              style: TextStyle(fontSize: 32),
                            ),
                            onPressed: () {},
                          ),
                        ],
                      ),
                    ),
                  ),
                  likeButton: StoryCardLikeButton(),
                  forwardButton: StoryCardForwardButton(),
                ),
                child: const Center(
                  child: Text(
                    "This is the story card widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              )
            ],
          )
        ],
      ),
    ),
  );
}

StoryCardLikeButton Usage

Using the StoryCardLikeButton

Manually change the StoryCardLikeButton properties.

PropertiesData TypeDescription
colorColorThe color of the StoryCardLikeButton.
iconIconDataA Icon Widget that is placed in right of the StoryCardMessageBox. Gets a IconData.
iconSizedoubleThe iconSize of the StoryCardLikeButton.
onLikeValueChanged<StoryCardLike>This callback is called when previous StoryCard is displayed. Returns a StoryCardLike that includes the card index and liked.

StoryCardLikeButton

StoryCardFooter includes likeButton: StoryCardLikeButton

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story(
        children: [
          StoryUser(
            avatar: Image.asset("assets/user_avatar.jpg"),
            label: const Text("UserName"),
            children: const [
              StoryCard(
                footer: StoryCardFooter(
                  likeButton: StoryCardLikeButton(),
                  child: Text(
                    "This is the story card footer widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
                child: Center(
                  child: Text(
                    "This is the story card widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              )
            ],
          )
        ],
      ),
    ),
  );
}

StoryCardForwardButton Usage

Using the StoryCardForwardButton

Manually change the StoryCardForwardButton properties.

PropertiesData TypeDescription
colorColorThe color of the StoryCardForwardButton.
iconIconDataA Icon Widget that is placed in right of the StoryCardMessageBox. Gets a IconData.
iconSizedoubleThe iconSize of the StoryCardForwardButton.
childWidgetCreates a layout widget on the StoryCard.
onForwardValueChanged<int>This callback is called when previous StoryCard is displayed. Returns a card index of the StoryCard list.

StoryCardForwardButton

StoryCardFooter includes forwardButton: StoryCardForwardButton

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story(
        children: [
          StoryUser(
            avatar: Image.asset("assets/user_avatar.jpg"),
            label: const Text("UserName"),
            children: const [
              StoryCard(
                footer: StoryCardFooter(
                  likeButton: StoryCardLikeButton(),
                  forwardButton: StoryCardForwardButton(),
                  child: Text(
                    "This is the story card footer widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
                child: Center(
                  child: Text(
                    "This is the story card widget",
                    style: TextStyle(color: Colors.white),
                  ),
                ),
              )
            ],
          )
        ],
      ),
    ),
  );
}

StoryController

Using the StoryController

Manually change the Story state. For better performance, use a StoryController as controller (recommended).

PropertiesData TypeDescription
isAttachedboolDetermine if the Story.controller is attached to an instance of the Story (this property must be true before any other StoryController functions can be used).
isAutoplayboolReturns whether or not the Story is Autoplay.
MethodsReturn TypeDescription
pauseStory()voidPauses the Story.
playStory()voidPlays the Story.
closeStory()voidCloses the Story.
openStory()voidOpens the Story. If the cardIndex null, default cardIndex is not StoryCard.visited.
openStoryByUserId()voidOpens the Story by StoryUser.userId. If the cardIndex null, default cardIndex is not StoryCard.visited.
setStoryCardVisited()voidSets a value for the StoryCard.visited.
setStoryCardVisitedByUserId()voidSets a value for the StoryCard.visited by StoryUser.userId.
StoryControllerStoryController
StoryController storyController = StoryController();

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Story(
            controller: storyController,
            children: [
              StoryUser(
                userId: 1,
                avatar: Image.asset("assets/user_avatar.jpg"),
                label: const Text("UserName"),
                children: [
                  StoryCard(
                    childOverlay: Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          ElevatedButton(
                            onPressed: () => storyController.pauseStory(),
                            child: const Text("Pause"),
                          ),
                          ElevatedButton(
                            onPressed: () => storyController.playStory(),
                            child: const Text("Play"),
                          ),
                          ElevatedButton(
                            onPressed: () =>
                                storyController.setStoryCardVisited(
                                    storyIndex: 0,
                                    cardIndex: 0,
                                    visited: true),
                            child: const Text("Set story card visited"),
                          ),
                          ElevatedButton(
                            onPressed: () =>
                                storyController.setStoryCardVisitedByUserId(
                                    userId: 1, cardIndex: 0, visited: true),
                            child: const Text(
                                "Set story card visited by user id"),
                          ),
                          ElevatedButton(
                            onPressed: () => storyController.closeStory(),
                            child: const Text("Close"),
                          ),
                        ],
                      ),
                    ),
                  )
                ],
              )
            ],
          ),
          Center(
            child: Column(
              children: [
                ElevatedButton(
                  onPressed: () => storyController.openStory(context,
                      storyIndex: 0, cardIndex: 0),
                  child: const Text("Open story"),
                ),
                ElevatedButton(
                  onPressed: () => storyController.openStoryByUserId(context,
                      userId: 1, cardIndex: 0),
                  child: const Text("Open story by user id"),
                ),
              ],
            ),
          )
        ],
      ),
    ),
  );
}

StoryBuilder

Using the Story.builder

see example/lib/main.dart

StoryController storyController = StoryController();
late List<StoryModel> stories;

@override
void initState() {
  super.initState();
  stories = getStories();
}

@override
void dispose() {
  super.dispose();
  storyController.dispose();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: SafeArea(
      child: Story.builder(
          controller: storyController,
          itemCount: stories.length,
          itemBuilder: (context, index) {
            return StoryUser(
              avatar: stories[index].avatar,
              label: stories[index].label,
              children: stories[index].cards == null
                  ? []
                  : stories[index].cards!.map((card) =>
                  StoryCard(
                    color: card.color,
                    cardDuration: card.duration,
                    childOverlay: card.childOverlay,
                    visited: card.visited,
                    onVisited: (cardIndex) {
                      setState(() {
                        card.visited = true;
                      });
                    },
                    child: card.child,
                  )).toList(),
            );
          }),
    ),
  );
}

List<StoryModel> getStories() {
  return [
    StoryModel(
        avatar: Image.asset("assets/user_avatar.jpg"),
        label: const Text("UserName"),
        cards: [
          StoryCardModel(
            child: const Center(
              child: Text(
                "This is the story card widget",
                style: TextStyle(color: Colors.white),
              ),
            ),
          )
        ]
    ),
  ];
}

class StoryModel {
  StoryModel({
    this.userId,
    this.avatar,
    this.label,
    this.cards,
  });

  int? userId;
  Widget? avatar;
  Text? label;
  List<StoryCardModel>? cards;
}

class StoryCardModel {
  StoryCardModel({
    this.visited = false,
    this.duration = const Duration(seconds: 2),
    this.color = const Color(0xff333333),
    this.childOverlay,
    this.child,
  });

  bool visited;
  Duration duration;
  Color color;
  Widget? childOverlay;
  Widget? child;
}