flutter pageview 样式

const _horizontalPadding = 32.0;

const _carouselItemMargin = 8.0;

const _carouselHeightMin = 200.0 + _carouselItemMargin * 2;

 

class Carousel extends StatefulWidget {

  final List<Widget> carousel;

  final AnimationController controller;

  const Carousel({Key key, this.carousel, this.controller}) : super(key: key);

  @override

  CarouselState createState() => CarouselState();

}

 

class CarouselState extends State<Carousel> {

  PageController _controller;

  int _currentPage = 0;

  @override

  void didChangeDependencies() {

    super.didChangeDependencies();

    if (_controller == null) {

      double padding = (_horizontalPadding - _carouselItemMargin) * 2;

      double width = MediaQuery.of(context).size.width;

      _controller = PageController(

          initialPage: 0, viewportFraction: (width - padding) / width);

    }

  }

 

  @override

  void dispose() {

    super.dispose();

    _controller.dispose();

  }

 

  Widget builder(int index) {

    final carouselCard = AnimatedBuilder(

      animation: _controller,

      builder: (BuildContext context, Widget child) {

        double value;

        bool haveDimension = _controller.position.haveDimensions;

        if (haveDimension) {

          double page = _controller.page;

          value = page - index;

        } else {

          value = (_currentPage - index).toDouble();

        }

 

        value = (1 - value.abs() * .38).clamp(0, 1).toDouble();

        value = Curves.easeOut.transform(value);

 

        return Center(

          child: Transform(

            transform: Matrix4.diagonal3Values(1.0, value, 1.0),

            alignment: Alignment.center,

            child: child,

          ),

        );

      },

      child: widget.carousel[index],

    );

    if (index == 1) {

      return AnimationCarouselCard(

          childer: carouselCard, controller: widget.controller);

    } else {

      return carouselCard;

    }

  }

 

  @override

  Widget build(BuildContext context) {

    return AnimationCarousel(

      animationController: widget.controller,

      childer: PageView.builder(

        physics: BouncingScrollPhysics(),

        allowImplicitScrolling: true,

        itemCount: widget.carousel.length,

        controller: _controller,

        onPageChanged: (value) {

          setState(() {

            _currentPage = value;

          });

        },

        itemBuilder: (BuildContext context, int index) => builder(index),

      ),

    );

  }

}

 

class AnimationCarousel extends StatelessWidget {

  AnimationCarousel(

      {Key key, @required this.animationController, @required this.childer})

      : startPositionAnimation = Tween(begin: 1.0, end: 0.0).animate(

            CurvedAnimation(

                parent: animationController,

                curve: const Interval(0.200, 0.800, curve: Curves.ease))),

        super(key: key);

 

  final AnimationController animationController;

  final Widget childer;

  final Animation<double> startPositionAnimation;

 

  @override

  Widget build(BuildContext context) {

    return LayoutBuilder(

      builder: (BuildContext context, BoxConstraints constraints) {

        return Stack(

          children: [

            SizedBox(height: _carouselHeightMin),

            AnimatedBuilder(

              animation: animationController,

              builder: (BuildContext context, Widget child) {

                return PositionedDirectional(

                  child: child,

                  start: constraints.maxWidth * startPositionAnimation.value,

                );

              },

              child: Container(

                height: _carouselHeightMin,

                width: constraints.maxWidth,

                child: childer,

              ),

            ),

          ],

        );

      },

    );

  }

}

 

class AnimationCarouselCard extends StatelessWidget {

  final Widget childer;

  final AnimationController controller;

  final Animation<double> startPositionAnimation;

 

  AnimationCarouselCard(

      {Key key, @required this.childer, @required this.controller})

      : startPositionAnimation = Tween(begin: _horizontalPadding, end: 0.0)

            .animate(CurvedAnimation(

                parent: controller,

                curve: Interval(0.800, 1.000, curve: Curves.ease))),

        super(key: key);

  @override

  Widget build(BuildContext context) {

    return AnimatedBuilder(

        animation: controller,

        builder: (context, child) {

          return Padding(

              padding: EdgeInsetsDirectional.only(

                  start: startPositionAnimation.value),

              child: childer);

        },

        child: childer);

  }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值