Flutter仿掘金点赞效果

Flutter仿掘金点赞效果,第1张

概述老孟导读:今天分享一下如何实现掘金点赞效果,这不仅仅是一篇技术文章,还是一篇解决问题思路的文章,遇到一个需求时,如何拆分需求,然后一步一步实现,这个过程比单纯的技术(此文)更有含金量。 先来看一下掘金

老孟导读:今天分享一下如何实现掘金点赞效果,这不仅仅是一篇技术文章,还是一篇解决问题思路的文章,遇到一个需求时,如何拆分需求,然后一步一步实现,这个过程比单纯的技术(此文)更有含金量。

先来看一下掘金点赞的效果:

说点题外话,感谢一下二哥@H_404_18@(沉默王二@H_404_18@ ),给了我很多建议和帮助,公众号搜索沉默王二@H_404_18@即可关注。

遇到组合动画效果时,首先拆分一下这个动画,以掘金点赞效果为例,共分为3个动画效果:

小手@H_404_18@图标改变颜色并且缩放一下。圆环@H_404_18@由粗变细,透明度逐渐变为0。最外圈小点点@H_404_18@透明度逐渐变为0。

拆分好了之后,就一步一步实现其效果。

小手缩放效果

小手@H_404_18@缩放效果需要2个图标,选中和未选中两种状态,我从阿里的图标库中选了2个类似的图标(未找到一摸一样的)。两种状态的图标定义如下:

////// 未点赞icon///const Icon _unlikeIcon = Icon(  IconData(0xe60a,FontFamily: 'appIconFonts'),);////// 点赞icon///const Icon _likeIcon = Icon(  IconData(0xe60c,color: color(0xFF1afa29),);

关于如何使用阿里的图标库中的图标可以查看此文章。

由于小手@H_404_18@图标的动画效果是放大->还原,使用组合动画实现其效果,代码如下:

@overrIDeinitState() {  _animationController =      AnimationController(duration: Duration(milliseconds: 300),vsync: this);  _iconAnimation = Tween(begin: 1.0,end: 1.3).animate(_animationController);  _iconAnimation = TweenSequence([    TweenSequenceItem(        tween: Tween(begin: 1.0,end: 1.3)            .chain(CurveTween(curve: Curves.easeIn)),weight: 50),TweenSequenceItem(tween: Tween(begin: 1.3,end: 1.0),]).animate(_animationController);}@overrIDe  Widget build(BuildContext context) {    return _buildlikeIcon();  }_buildlikeIcon() {    return ScaleTransition(      scale: _iconAnimation,child: Widget.like          ? Iconbutton(              padding: EdgeInsets.all(0),icon: _likeIcon,onpressed: () {                _clickIcon();              },)          : Iconbutton(              padding: EdgeInsets.all(0),icon: _unlikeIcon,),);  }

添加按钮点击效果:

_clickIcon() {  if (_iconAnimation.status == AnimationStatus.forward ||      _iconAnimation.status == AnimationStatus.reverse) {    return;  }  setState(() {    Widget.like = !Widget.like;  });  if (_iconAnimation.status == AnimationStatus.dismissed) {    _animationController.forward();  } else if (_iconAnimation.status == AnimationStatus.completed) {    _animationController.reverse();  }}

圆环动画

圆环的动画效果是线条宽度逐渐变为0,透明度逐渐变为0,相对简单,使用AnimatedBuilder@H_404_18@实现:

_buildCircle() {  return !Widget.like      ? Container()      : AnimatedBuilder(          animation: _circleAnimation,builder: (BuildContext context,Widget child) {            return Container(              decoration: Boxdecoration(                  shape: BoxShape.circle,border: border.all(                      color: color(0xFF5FA0EC)                          .withOpacity(_circleAnimation.value),wIDth: _circleAnimation.value * 8)),);          },);}

定义_circleAnimation@H_404_18@:

_circleAnimation =    Tween(begin: 1.0,end: 0.0).animate(_animationController);

最外圈小点点

最外圈的小点点动画效果是最简单的,透明度逐渐变为0,但布局相对复杂,围绕小手@H_404_18@形成一个圆形,使用Flow@H_404_18@实现此布局,Flow@H_404_18@是一个非常酷炫的布局组件,更多用法查看此文。

构建单个小圆点

_buildCirclePoint(double radius,color color) {  return !Widget.like      ? Container()      : AnimatedBuilder(          animation: _circleAnimation,Widget child) {            return Container(              wIDth: radius,height: radius,decoration: Boxdecoration(                  shape: BoxShape.circle,color: color.withOpacity(_circleAnimation.value)),);}

构建围绕小手@H_404_18@的多个点:

_buildCirclePoints() {  return Flow(    delegate: CirclePointFlowDelegate(),children: <Widget>[      _buildCirclePoint(2,color(0xFF97B1CE)),_buildCirclePoint(5,color(0xFF4AC6B7)),_buildCirclePoint(2,],);}

CirclePointFlowDelegate 定义如下:

class CirclePointFlowDelegate extends FlowDelegate {  CirclePointFlowDelegate();  @overrIDe  voID paintChildren(FlowPaintingContext context) {    var radius = min(context.size.wIDth,context.size.height) / 2.0;    //中心点    double rx = radius;    double ry = radius;    for (int i = 0; i < context.childCount; i++) {      if (i % 2 == 0) {        double x =            rx + (radius - 5) * cos(i * 2 * pi / (context.childCount - 1));        double y =            ry + (radius - 5) * sin(i * 2 * pi / (context.childCount - 1));        context.paintChild(i,transform: Matrix4.translationValues(x,y,0));      } else {        double x = rx +            (radius - 5) *                cos((i - 1) * 2 * pi / (context.childCount - 1) +                    2 * pi / ((context.childCount - 1) * 3));        double y = ry +            (radius - 5) *                sin((i - 1) * 2 * pi / (context.childCount - 1) +                    2 * pi / ((context.childCount - 1) * 3));        context.paintChild(i,0));      }    }  }  @overrIDe  bool shouldRepaint(FlowDelegate oldDelegate) => true;}

交流

老孟Flutter博客地址(近200个控件用法):http://laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

总结

以上是内存溢出为你收集整理的Flutter仿掘金点赞效果全部内容,希望文章能够帮你解决Flutter仿掘金点赞效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1000393.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存