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

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

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

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

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

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

小手缩放效果

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

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

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

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

@override
initState() {
_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), weight: 50),
]).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,
onPressed: () {
_clickIcon();
},
),
);
}

添加按钮点击效果:

_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实现:

_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

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

最外圈小点点

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

构建单个小圆点

_buildCirclePoint(double radius, Color color) {
return !widget.like
? Container()
: AnimatedBuilder(
animation: _circleAnimation,
builder: (BuildContext context, Widget child) {
return Container(
width: radius,
height: radius,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color.withOpacity(_circleAnimation.value)),
);
},
);
}

构建围绕小手的多个点:

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

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, transform: Matrix4.translationValues(x, y, 0));
}
}
} @override
bool shouldRepaint(FlowDelegate oldDelegate) => true;
}

交流

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

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

Flutter仿掘金点赞效果的更多相关文章

  1. Android -- 自定义ViewGroup+贝塞尔+属性动画实现仿QQ点赞效果

    1,昨天我们写了篇简单的贝塞尔曲线的应用,今天和大家一起写一个QQ名片上常用的给别人点赞的效果,实现效果图如下: 红心的图片比较丑,见谅见谅(哈哈哈哈哈哈).... 2,实现的思路和原理 从上面的效果 ...

  2. Android -- 《 最美有物》好看的点赞效果

    1,前天在鸿洋的公众号上看到一款不错的点赞效果,是仿最美有物的点赞,再加上自己最近学习状态很差,自己想着通过这个效果练手一下,果然,花了整整两天的时间,按照以前的效率的话一天就够了,哎,已经调整了一个 ...

  3. Flutter 仿滴滴出行App

    绿色出行 Flutter 仿滴滴出行App 地图:采用高德地图,仅简单完成了部分功能,基础地图,地址检索,逆地理编码. 界面:仿滴滴主界面,地图中心请求动效果,服务tabs展开效果,地址检索界面,城市 ...

  4. Android仿IOS回弹效果 ScrollView回弹 总结

    Android仿IOS回弹效果  ScrollView回弹 总结 应项目中的需求  须要仿IOS 下拉回弹的效果 , 我在网上搜了非常多 大多数都是拿scrollview 改吧改吧 试了一些  发现总 ...

  5. PHP实现仿Google分页效果的分页函数

    本文实例讲述了PHP实现仿Google分页效果的分页函数.分享给大家供大家参考.具体如下: /** * 分页函数 * @param int $total 总页数 * @param int $pages ...

  6. Android类似Periscope点赞效果

    原文   https://github.com/AlanCheen/PeriscopeLayout 主题 安卓开发 PeriscopeLayout A layout with animation li ...

  7. 原生wcPop.js消息提示框(移动端)、内含仿微信弹窗效果

    wcPop.js移动端消息对话框插件是之前的wxPop.js的升级版,优化了js和css,并且新增了仿微信弹窗效果, 是一款含有多种情景模式的原生模态消息对话框代码,可用于替代浏览器默认的alert弹 ...

  8. EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  9. jquery 仿windows10菜单效果下载

    http://www.kuitao8.com/20150923/4079.shtml jquery 仿windows10菜单效果下载

随机推荐

  1. 消息中间件metaq

    消息中间件metaq安装并注册到zookper集群 项目地址 https://github.com/killme2008/Metamorphosis Memorphosis是一个消息中间件,它是lin ...

  2. Docker镜像与仓库(四)

    Dockerfile方式创建镜像 https://hub.docker.com/_/centos/ #找一个centos6.6 的dockerfile链接 [root@linux-node1 ~]# ...

  3. java 设计模式-责任链

    责任链设计模式,其实就是处理同一个请求的对象连接成一条链,请求的路径经过这条链,符合要求的就处理这个请求,不符合就接着往下面抛出,直道有人处理这条请求. 业务:比如啊,公司个人请假,三天以下就是主管审 ...

  4. 自定义fastjson对枚举类型的序列化及反序列化过程

    通常,fastjson在序列化及反序列化枚举时,一般以下几种策略: 1).根据枚举的name值序列化及反序列化(默认) 2).根据枚举的ordinal序列化及反序列化 3).根据枚举的toString ...

  5. CodeForces - 1047A

    A. Little C Loves 3 I time limit per test1 second memory limit per test256 megabytes inputstandard i ...

  6. P1522 牛的旅行 Cow Tours(floyd)

    题目描述 农民 John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通.这样,Farmer John就有多个 ...

  7. centos7 安装高版本svn

    一.安装高版本svn 1.创建一个新的yum库文件,vim /etc/yum.repos.d/wandisco-svn.repo 内容如下 [WandiscoSVN] name=Wandisco SV ...

  8. async与await----js的异步处理

    async与await----js的异步处理 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 之前写代码遇到一个问题,返回 ...

  9. A Simple Problem with Integers 循环节 修改 平方 找规律 线段树

    A Simple Problem with Integers 这个题目首先要打表找规律,这个对2018取模最后都会进入一个循环节,这个循环节的打表要用到龟兔赛跑. 龟兔赛跑算法 floyed判环算法 ...

  10. Java 经典面试题:聊一聊 JUC 下的 LinkedBlockingQueue

    本文聊一下 JUC 下的 LinkedBlockingQueue 队列,先说说 LinkedBlockingQueue 队列的特点,然后再从源码的角度聊一聊 LinkedBlockingQueue 的 ...