santa112358 / story

Instagram stories like UI with rich animations and customizability.
https://pub.dev/packages/story
MIT License
42 stars 61 forks source link
instagram stories

version likes popularity License: MIT all contributors

Instagram stories like UI with rich animations and customizability.

final 2

Usage

StoryPageView requires at least three arguments: itemBuilder, pageLength, and storyLength.

/// Minimum example to explain the usage.
return Scaffold(
  body: StoryPageView(
    itemBuilder: (context, pageIndex, storyIndex) {
      return Center(
        child: Text("Index of PageView: $pageIndex Index of story on each page: $storyIndex"),
      );
    },
    storyLength: (pageIndex) {
      return 3;
    },
    pageLength: 4,
  );

The example above just shows 12 stories by 4 pages, which is not practical.

This one is the proper usage, extracted from example.

return Scaffold(
  body: StoryPageView(
    itemBuilder: (context, pageIndex, storyIndex) {
      final user = sampleUsers[pageIndex];
      final story = user.stories[storyIndex];
      return Stack(
        children: [
          Positioned.fill(
            child: Container(color: Colors.black),
          ),
          Positioned.fill(
            child: Image.network(
              story.imageUrl,
              fit: BoxFit.cover,
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(top: 44, left: 8),
            child: Row(
              children: [
                Container(
                  height: 32,
                  width: 32,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: NetworkImage(user.imageUrl),
                      fit: BoxFit.cover,
                    ),
                    shape: BoxShape.circle,
                  ),
                ),
                const SizedBox(
                  width: 8,
                ),
                Text(
                  user.userName,
                  style: TextStyle(
                    fontSize: 17,
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
        ],
      );
    },
    gestureItemBuilder: (context, pageIndex, storyIndex) {
      return Align(
        alignment: Alignment.topRight,
        child: Padding(
          padding: const EdgeInsets.only(top: 32),
          child: IconButton(
            padding: EdgeInsets.zero,
            color: Colors.white,
            icon: Icon(Icons.close),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
      );
    },
    pageLength: sampleUsers.length,
    storyLength: (int pageIndex) {
      return sampleUsers[pageIndex].stories.length;
    },
    onPageLimitReached: () {
      Navigator.pop(context);
    },
  ),
);

In this case, IconButton to close the page is in the callback.

You CANNOT place the gesture widgets in itemBuilder as they are covered and disabled by the default story gestures.

/// Example Data Model
class UserModel {
  UserModel(this.stories, this.userName, this.imageUrl);

  final List<StoryModel> stories;
  final String userName;
  final String imageUrl;
}

class StoryModel {
  StoryModel(this.imageUrl);

  final String imageUrl;
}

StoryImage

If you show images in StoryPageView, use StoryImage. It can stop the indicator until the image is fully loaded.

StoryImage(
  /// key is required
  key: ValueKey(story.imageUrl),
  imageProvider: NetworkImage(
    story.imageUrl,
  ),
  fit: BoxFit.fitWidth,
)

Be sure to assign the unique key value for each image, otherwise the image loading will not be handled properly.

indicatorAnimationController

If you stop/start the animation of the story with your custom widgets, use indicatorAnimationController

class _StoryPageState extends State<StoryPage> {
  late ValueNotifier<IndicatorAnimationCommand> indicatorAnimationController;

  @override
  void initState() {
    super.initState();
    indicatorAnimationController = ValueNotifier<IndicatorAnimationCommand>(
        IndicatorAnimationCommand.resume);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StoryPageView(
        indicatorAnimationController: indicatorAnimationController,
        ...,
      ),
    );
  }
}

Once the instance is passed to StoryPageView, you can stop handle the indicator by the methods below.


/// To pause the indicator
indicatorAnimationController.value = IndicatorAnimationCommand.pause;

/// To resume the indicator
indicatorAnimationController.value = IndicatorAnimationCommand.resume;

Contributors

Santa Takahashi
Santa Takahashi

💻
Isaias Mejia de los Santos
Isaias Mejia de los Santos

💻
Медик
Медик

💻
Alperen Soysal
Alperen Soysal

💻
AtixD
AtixD

💻
harshitFinmapp
harshitFinmapp

💻
dmitry-kotorov
dmitry-kotorov

💻
sachin kumar rajput
sachin kumar rajput

💻
Mohamed Othman
Mohamed Othman

💻