change story items as dynamic widgets in flutter

Issue

I want to implement story items as different widgets. Like in this example:

pic

In this picture, only images are changed, but I want to change as whole widgets as story items.

I have tried the story_view package. But, in this package, only images and videos can be added. Is there any other library for that?

Solution

As explained by https://stackoverflow.com/users/8164116/daksh-gargas, story view can be easily implemented using stack pageview and a simple gesture detector.

Made a simple story view –

import 'package:flutter/material.dart';

class CustomStoryView extends StatefulWidget{
  @override
  _CustomStoryViewState createState() => _CustomStoryViewState();
}

class _CustomStoryViewState extends State<CustomStoryView> with SingleTickerProviderStateMixin {
  final List _colorsList = [Colors.blue, Colors.red, Colors.green, Colors.yellow, Colors.grey, Colors.brown];
  final PageController _controller = PageController();
  double _progressIndicators;
  int _page = 0;
  AnimationController _animationController;
  bool dragEnded = true;
  Size _pageSize;
  @override
  void initState() {
    _animationController = AnimationController(vsync: this, duration: Duration(seconds: 2));
    _animationController.addListener(animationListener);
    _animationController.forward();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      _pageSize = MediaQuery.of(context).size;
      _progressIndicators = (_pageSize.width - 100) / 6;
    });
    super.initState();
  }

  @override
  void dispose() {
    _animationController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          PageView.builder(
            controller: _controller,
            physics: NeverScrollableScrollPhysics(),
            itemBuilder: (context, index)=>GestureDetector(
              onLongPressStart: _onLongPressStart,
              onLongPressEnd: _onLongPressEnd,
              onHorizontalDragEnd: _onHorizontalDragEnd,
              onHorizontalDragStart: _onHorizontalDragStart,
              onHorizontalDragUpdate: _onHorizontalDragUpdate,
              onTapUp: _onTapDown,
              child: Container(
              height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
              color: _colorsList[index],
                child: Center(child: InkWell(
                    onTap: (){
                      print("thiswasclicked $index");
                    },
                    child: Text("Somee random text", style: TextStyle(fontSize: 36),)),),
          ),
            ),
          itemCount: _colorsList.length,
          ),
          Positioned(
            top: 48,
            left: 0,
            right: 0,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: ([0,1,2,3,4,5].map((e) =>
              (e == _page) ? Stack(
                children: [
                  Container(
                    width: _progressIndicators,
                    height: 8 ,
                    color: Colors.black54,
                  ),
                  AnimatedBuilder(
                    animation: _animationController,
                    builder: (ctx, widget){
                      return AnimatedContainer(
                        width: _progressIndicators * _animationController.value,
                        height: 8 ,
                        color: Colors.white,
                        duration: Duration(milliseconds: 100),
                      );
                    },

                  ),
                ],
              ): Container(
                width: _progressIndicators,
                height: 8 ,
                color: (_page >= e) ? Colors.white : Colors.black54,
              )).toList()),
            ),)
        ],
      ),
    );
  }

  animationListener(){
    if(_animationController.value == 1){
      _moveForward();
    }
  }

  _moveBackward(){
   if(_controller.page != 0){
     setState(() {
       _page = (_controller.page - 1).toInt();
       _page = (_page < 0) ? 0 : _page;
       _controller.animateToPage(_page, duration: Duration(milliseconds: 100), curve: Curves.easeIn);
       _animationController.reset();
       _animationController.forward();
     });
   }
  }

  _moveForward(){
   if(_controller.page != (_colorsList.length - 1)){
     setState(() {
       _page = (_controller.page + 1).toInt();
       _controller.animateToPage(_page, duration: Duration(milliseconds: 100), curve: Curves.easeIn);
       _animationController.reset();
       _animationController.forward();
     });
   }
  }
  _onTapDown(TapUpDetails details) {
    var x = details.globalPosition.dx;
    (x < _pageSize.width / 2) ? _moveBackward() : _moveForward();
  }

  _onHorizontalDragUpdate(d){
    if (!dragEnded) {
      dragEnded = true;
      if (d.delta.dx < -5) {
        _moveForward();
      } else if (d.delta.dx > 5) {
        _moveBackward();
      }
    }
  }
  _onHorizontalDragStart(d) {
    dragEnded = false;
  }

  _onHorizontalDragEnd(d) {
  dragEnded = true;
  }

  _onLongPressEnd(_){
  _animationController.forward();
  }

  _onLongPressStart(_){
  _animationController.stop();
  }
}

Answered By – Sharan Singh

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.