ig_story 0.0.2

Flutter Android iOS web

Stories like Instagram.

ig_story #

A player widget to implement Stories like Instagram.

Installation #

To use this plugin, add ig_story as a dependency in your pubspec.yaml file.

Usage #

Import the package into your code

import "package:ig_story/ig_story.dart";

Basics #

12850023488720_2

  1. Define IgManager to control the story's animation.
  2. Create widgets which you want to display.
  3. Wrap each of them with IgChild.
  4. Pass the IgChilds to IgStory. That's it.

Example #

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  // Manager to control animation.
  IgManager manager = IgManager();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: IgStory(
        manager: manager,
        children: [
          // Basic Widget
          IgChild(
            // Optional
            duration: Duration(seconds: 2),
            // Required: Any widget can be set.
            child: Container(
              color: Colors.red,
              child: Center(
                child: Text(
                  'first page',
                  style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                ),
              ),
            ),
          ),
          IgChild(
            child: Container(
              color: Colors.green,
              child: Center(
                child: Text(
                  'second page',
                  style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                ),
              ),
            ),
          ),
          // Advanced usage
          // After finished loading, trigger story animations.
          IgChild(
            child: Container(
              width: double.infinity,
              height: double.infinity,
              child: MyImageLoader(
                manager: manager,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// Example image loader widget.
// it's not this library's widget.
class MyImageLoader extends StatefulWidget {
  final IgManager manager;
  MyImageLoader({@required this.manager});
  State createState() => new MyImageLoaderState();
}

class MyImageLoaderState extends State<MyImageLoader> {
  Image _image = new Image.network(
    'https://img.gifmagazine.net/gifmagazine/images/4407234/original.gif',
    fit: BoxFit.cover,
  );
  bool _loading = true;

  @override
  void initState() {
    super.initState();
    _image.image
        .resolve(ImageConfiguration())
        .addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
      if (mounted) {
        // Calls play() method after finished loading all image data.
        widget.manager.play();
        setState(() {
          _loading = false;
        });
      }
    }));
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        backgroundColor: Colors.black,
        body: Container(
          width: double.infinity,
          height: double.infinity,
          child: _loading ? new Text('Loading...') : _image,
        ),
      ),
    );
  }
}

Advanced #

12850023488720

You can use IgStories which is the wrapper to wrap up IgStory widgets. The IgStory widget wrapped IgStories is animated to next IgStory widget smoothly like Instagram's cube transition.

Example #

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  IgManager manager = IgManager();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: IgStories(
        manager: manager,
        children: [
          // User A's Story
          IgStory(
            manager: manager,
            children: [
              IgChild(
                child: Container(
                  color: Colors.red,
                  child: Center(
                    child: Text(
                      'first page',
                      style:
                          TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
              ),
              IgChild(
                duration: Duration(seconds: 2),
                child: Container(
                  color: Colors.green,
                  child: Center(
                    child: Text(
                      'second page',
                      style:
                          TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
              ),
              IgChild(
                child: Container(
                  width: double.infinity,
                  height: double.infinity,
                  child: LoadedImage(
                    manager: manager,
                    url:
                        "https://img.gifmagazine.net/gifmagazine/images/4407234/medium_thumb.png",
                  ),
                ),
              ),
            ],
          ),
          // User B's Story
          IgStory(
            manager: manager,
            children: [
              IgChild(
                child: Container(
                  color: Colors.blue,
                  child: Center(
                    child: Text(
                      'first page',
                      style:
                          TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
              ),
              IgChild(
                child: Container(
                  width: double.infinity,
                  height: double.infinity,
                  child: LoadedImage(
                    manager: manager,
                    url:
                        "https://img.gifmagazine.net/gifmagazine/images/4381451/medium_thumb.png",
                  ),
                ),
              ),
            ],
          )
        ],
      ),
    );
  }

  @override
  void dispose() {
    manager.controller.close();
    super.dispose();
  }
}

class LoadedImage extends StatefulWidget {
  final String url;
  final IgManager manager;
  LoadedImage({@required this.manager, @required this.url});
  State createState() => new LoadedImageState();
}

class LoadedImageState extends State<LoadedImage> {
  Image _image;
  bool _loading = true;

  @override
  void initState() {
    super.initState();
    _image = Image.network(
      widget.url,
      fit: BoxFit.cover,
    );
    _image.image
        .resolve(ImageConfiguration())
        .addListener(ImageStreamListener((ImageInfo info, bool syncCall) {
      if (mounted) {
        widget.manager.play();
        setState(() {
          _loading = false;
        });
      }
    }));
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        backgroundColor: Colors.black,
        body: Container(
          width: double.infinity,
          height: double.infinity,
          child: _loading ? new Text('Loading...') : _image,
        ),
      ),
    );
  }
}