可以有多个水滴,可以控制位置,水滴上下浮动。点击水滴产生搜集动画,水滴向树移动并逐渐消失,如图:

那么是如何实现的呢,下面我们一步步来分析:

1、定义一个继承Relativelayout 的子类作为容器放置多个水滴并在Onlayout()中设置子控件的位置

@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {final int count = getChildCount();for (int i = 0; i < count; i++) {View child = getChildAt(i);int childWidth = child.getMeasuredWidth();int childHeight = child.getMeasuredHeight();if (child.getVisibility() != GONE) {child.layout(listX.get(i), listY.get(i), childWidth + listX.get(i), childHeight + listY.get(i));}}}

上面代码最重要的就是child.layout()函数,前两个参数为子控件的位置,这我先去盗个图:

如图,前两个参数分别为getLeft 和getTop,后两个参数分别为getRight和getBottom;前两个参数其实是我们重外界传进来的子坐标列表,代码如下:

List<Integer> listX = new ArrayList<>();List<Integer> listY = new ArrayList<>();public void setChildPosition(int posx, int posy) {listX.add(posx);listY.add(posy);}

对于后面两个参数我们需要先获取子控件的宽高;然后在叠加上前面两个参数就是我们需要的坐标,在上面代码中可以看到我们是通过child.getmeasure来获取的宽高,但在获取宽高之前我们还需要去测量子空间的宽高。这个测量需要在measure()中完成:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);measureChildren(widthMeasureSpec, heightMeasureSpec);}

至此,我们的父容器已经设计完成,接下来我们需要自己定义子控件以及子控件的动画,首先是一个浮动的动画,因为我们这里后面需要监听点击动作,所以最好使用属性动画完成,如下:

private void doRepeatAnim() {ObjectAnimator animator = ObjectAnimator.ofFloat(this, "translationY", -padding, padding, -padding);animator.setRepeatMode(ObjectAnimator.REVERSE);animator.setRepeatCount(ObjectAnimator.INFINITE);animator.setDuration(1500);animator.start();}

就是让其沿Y轴上下移动,设置为INFINTE则为无限重复动画;第二个动画就是我们点击的时候,子控件会移动到某个特定的位置并逐渐消失:

 this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {doSetAnim();}});
private void doSetAnim() {if (isCollect) return;isCollect = true;ObjectAnimator move1 = ObjectAnimator.ofFloat(this, "translationX", startWidth, endWidth);ObjectAnimator move2 = ObjectAnimator.ofFloat(this, "translationY", startHeight, endHeight);ObjectAnimator move3 = ObjectAnimator.ofFloat(this, "alpha", 1, 0);AnimatorSet animatorSet = new AnimatorSet();animatorSet.playTogether(move1, move2, move3);animatorSet.setDuration(1500);animatorSet.start();}

里面我添加了isCollect 判断,用于处理点击事件重复生效的问题,这里是一个动画组合,重当前位置移动到特定位置同时透明度也不断的变淡。写动画的时候特别应该注意一个问题就是当前的所有位置都不是外面传进来的位置而是以当前控件初始位置为参考的相对位置,因为我们在父控件的时候就设定好了子控件的位置,不能再次进行重复设定不然会叠加,所以上面的startwidth 和startHeight其实都是0,endWidth 和endHeight也是结束位置减去控件移动的初始位置:

/*** @param context*/public WaterView(Context context) {super(context);this.context = context;endWidth = (int) DeviceUtils.dpToPixel(context, 160);endHeight = (int) DeviceUtils.dpToPixel(context, 300);padding = (int) DeviceUtils.dpToPixel(context, 10);startWidth = 0;startHeight = 0;}/*** @param index* @param startWidth  开始坐标 X* @param startHeight 开始坐标 Y*/public void setPosition(int index, int startWidth, int startHeight) {this.index = index;endWidth = endWidth - startWidth;endHeight = endHeight - startHeight;}

,在设置动画之前,我们还缺少初始化控件的步骤,这个步骤就是绘制背景控件,这个过程在ondraw()方法中进行:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mMWidth = getMeasuredWidth();mHeight = getMeasuredHeight();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(getResources().getColor(R.color.color_87d1ab));mPaint.setStyle(Paint.Style.FILL);canvas.drawCircle(mMWidth / 2, (float) mHeight / 2, DeviceUtils.dpToPixel(context, 30), mPaint);mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mTextPaint.setColor(Color.WHITE);mTextPaint.setTextSize(DeviceUtils.dpToPixel(context, 30));mTextPaint.setColor(getResources().getColor(R.color.text_color_fc));mTextPaint.setStyle(Paint.Style.FILL);float width = mTextPaint.measureText(text);canvas.drawText(text, mMWidth / 2 - width / 2, (float) mHeight * 0.65f, mTextPaint);doRepeatAnim();this.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View view) {doSetAnim();}});}

如上,我绘制了一个纯色的园和特定的文字。当子控件绘制完成后才进行的动画。

最后就是如何使用我们刚才做好了轮子啦,请看代码:

@Overrideprotected void onStart() {super.onStart();int posx = (int) DeviceUtils.dpToPixel(this, 70);int posy = (int) DeviceUtils.dpToPixel(this, 70);addChildView(this, relative, 1, posx, posy);addChildView(this, relative, 2, 2 * posx, 2 * posy);addChildView(this, relative, 3, 3 * posx, posy);}/*** 添加子水滴** @param relative* @param index    第几个* @param posx     子控件初始位置x* @param posy     子控件初始位置y*/private void addChildView(final Context context, final WaterContainer relative, final int index, final int posx, final int posy) {relative.postDelayed(new Runnable() {@Overridepublic void run() {int width = (int) DeviceUtils.dpToPixel(context, 60);int height = (int) DeviceUtils.dpToPixel(context, 60);ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(width, height);WaterView waterView = new WaterView(context);waterView.setPosition(index, posx, posy);waterView.setLayoutParams(layoutParams);relative.setChildPosition(posx, posy);relative.addView(waterView);}}, (index - 1) * 300);}

在添加代码里面,我添加了一个延时,这样每个添加的子水滴就会不同步的上下跳动,看起来更为真实,如果你有更好的办法请一定记得告诉我,上面的代码就是通过LayoutParams先设定子控件的布局,再把子控件添加到父容器中去。可以实现重复调用,就是这么简单。

最后给出项目的github地址:

https://github.com/yangyong915/UIDemo

如果你觉得对你有帮助,请记得star,万分感谢!

仿支付宝蚂蚁森林水滴浮动效果相关推荐

  1. android 水浮动的动画,Android实现支付宝蚂蚁森林水滴浮动效果

    可以有多个水滴,可以控制位置,水滴上下浮动.点击水滴产生搜集动画,水滴向树移动并逐渐消失,如图: 那么是如何实现的呢,下面我们一步步来分析: 1.定义一个继承Relativelayout 的子类作为容 ...

  2. html5仿蚂蚁森林效果代码,vue仿支付宝蚂蚁森林水滴

    APP 需要做一个类似蚂蚁森林的功能模块,动效和蚂蚁森林接近,可以有多个水滴,可以控制位置,水滴上下浮动. gif图如下所示: soogif.gif v-for="(item, index) ...

  3. Android 仿支付宝蚂蚁森林动画效果

    Android 动画可以归纳为以下几种: 视图动画(View 动画) 帧动画(Frame 动画.Drawable 动画) 属性动画 触摸反馈动画(Ripple Effect) 揭露动画(Reveal ...

  4. 仿支付宝蚂蚁森林效果

    CustomWaterView 项目地址:xiaohaibin/CustomWaterView  简介::star: 仿支付宝蚂蚁森林效果 更多:作者   提 Bug 标签: 实现原理文章:https ...

  5. php蚂蚁森林的效果,iOS仿支付宝蚂蚁森林动画效果

    最近要用到类似支付宝蚂蚁森林的动画效果,所以就简单写了一个比较简单的一个demo,效果图如下: 效果图1 需求: 在这个view上面随机出现n个黄钻(button),黄钻按钮还得上下抖动,箭头1指向的 ...

  6. 老司机带你顺手撸一个支付宝蚂蚁森林效果

    老司机,不存在的,其实我还算不上,哈哈... 最近公司产品突然有一个类似支付宝蚂蚁森林的功能,大致功能跟支付宝蚂蚁森林相像,在看了一下支付宝蚂蚁森林的效果之后,本来这种东西用RN实现是最好不过的,不过 ...

  7. 仿蚂蚁森林能量球效果遇到的问题记录

    仿蚂蚁森林能量球效果遇到的问题记录 常规先上图 前提内容 仿做一个蚂蚁森林的能量球效果,计划使用属性动画,来实现能量球上下摆动,然后点击能量球有一个收集的动画. 本来以为就这么几个简单的需求不会太难, ...

  8. 利用Auto.js自动收集支付宝蚂蚁森林能量小程序

    最近利用Auto.js写了一个支付宝蚂蚁森林自动收集自己能量和好友能量的小程序,现在发布出来共享给大家.程序在我的华为手机上运行效果非常好. //1.解锁屏幕 unlock(); //2.启用按键监听 ...

  9. 仿支付宝/微信的password输入框效果GridPasswordView解析

    仿支付宝/微信的password输入框效果GridPasswordView解析,把一些设置和一些关键的地方列了出来,方便大家使用,可能能够省一部分的时间,也算是自己的积累吧. 1.password框能 ...

最新文章

  1. Xilinx® 7 series FPGAs CLBs专题介绍(二)
  2. Android中实现滑动翻页—使用ViewFlipper
  3. 【统计学习】多元统计分析
  4. codesoft各个版本的 dll_win10安装pytorch-gpu版本
  5. 圆的半径java_css中的圆形边界半径工件
  6. Spring Cloud(二) Consul 服务治理实现
  7. windows系统里懒人的福音,如何实现不按住ctrl实现文件多选
  8. JfreeChart(八)之甘特图
  9. 浙江义乌计算机中专学校,浙江义乌有没有中专学校?
  10. 华为P50系列确定29日发布:但遗憾的是...
  11. 9.思科交换路由基本命令操作
  12. Arcgis Engine 添加一个Symbol符号样式步骤
  13. [AHOI 2009]chess 中国象棋
  14. showModalDialog和showModelessDialog中提交form不弹出新窗口
  15. 2015061410 - 推荐知乎周刊
  16. uniapp重新渲染页面_uni-app里面使用uni.request请求并且渲染列表
  17. HRT:使用Huge Pages进行低延迟优化
  18. 完爆面试官!黑马学java学费多少
  19. 具名元组namedtuple
  20. 考研380分什么水平计算机,考研总分500考380难吗 考研380分是什么水平

热门文章

  1. 几分钟让小孩的人物涂鸦「动起来」,Facebook AI创建了一个奇妙的火柴人世界
  2. 人工智能-强化学习:Imitation Learning(模仿学习)= Learning by Demonstration(示范学习)【每一步action都没有reward】
  3. 【项目精选】 塞北村镇旅游网站设计(视频+论文+源码)
  4. Java web集成支付宝电脑支付接口(沙箱环境)
  5. java 常量关键字_Java 常量 关键字final
  6. 目标跟踪算法——KCF入门详解
  7. 2018最新网易云课堂Python Flask框架全栈开发
  8. win7字体大小怎么设置_win7锁屏时间怎么设置
  9. RAMOS(全内存操作系统)初识----仅供测试
  10. 【Numpy库】【花哨索引】用python做数据分析所必须掌握的基础库之一 _03_ 花式(花哨)索引_fancy indexing