千家信息网

Android中怎么实现两颗小球转动效果

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,今天小编给大家分享一下Android中怎么实现两颗小球转动效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下
千家信息网最后更新 2026年11月04日Android中怎么实现两颗小球转动效果

今天小编给大家分享一下Android中怎么实现两颗小球转动效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

效果图如下所示:

本控件效果图:

使用方法

源码地址:Android仿抖音加载框之两颗小球转动控件

1、xml引用:

 

2、java使用:

 @BindView(R.id.dy1) DYLoadingView dy1; @OnClick(R.id.b1) void start() { dy1.setXXXXX; //设置属性(可选) dy1.start(); //开始动画 } @OnClick(R.id.b2) void stop() { dy1.stop(); //停止动画 }

就酱。

可用属性

名称对应xml属性对应java方法默认值
球1半径radius1setRadius()6dp
球2半径radius2setRadius()6dp
两球间隔gapsetRadius()0.8dp
球1颜色color1setColors()0XFFFF4040
球2颜色color2setColors()0XFF00EEEE
叠加色mixColorsetColors()0XFF000000
从右往左移动时小球最大缩放倍数rtlScalesetScales()0.7f
从左往右移动时小球最大缩放倍数ltrScalesetScales()1.3f
一次移动动画时长durationsetDuration()350ms
一次移动动画后停顿时长pauseDurationsetDuration()80ms
动画进度在[0,scaleStartFraction]期间,小球大小逐渐缩放scaleStartFractionsetStartEndFraction()0.2f
动画进度在[scaleEndFraction,1]期间,小球大小逐渐恢复scaleEndFractionsetStartEndFraction()0.8f

(rtl = right to left, ltr = left to right)

部分属性说明:

•color格式为32位ARGB
•scaleStartFraction范围[0,0.5];scaleEndFraction范围[0.5,1]
•假设ltrScale = 1.3,scaleStartFraction = 0.2,scaleEndFraction = 0.8;那么实际效果就是一颗小球从左边开始向右移动

期间,进度在0%~20%时半径逐渐从1倍放大到1.3倍,在20%~80%期间大小保持1.3倍,在80%~100%时半径逐渐从1.3倍恢复至1倍

实现思路

要让小球动,当然要有一个动画,通过动画来获得一个进度百分比fraction,然后小球在动画过程中的坐标、大小就可以通过这个值来计算:

 private void initAnim() { fraction = 0.0f; stop(); anim = ValueAnimator.ofFloat(0.0f, 1.0f); anim.setDuration(duration); if (pauseDuration > 0) {  anim.setStartDelay(pauseDuration);  anim.setInterpolator(new AccelerateDecelerateInterpolator()); } else {  anim.setRepeatCount(ValueAnimator.INFINITE);  anim.setRepeatMode(ValueAnimator.RESTART);  anim.setInterpolator(new LinearInterpolator()); } anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  @Override  public void onAnimationUpdate(ValueAnimator animation) {  fraction = animation.getAnimatedFraction();  invalidate();  } }); anim.addListener(new AnimatorListenerAdapter() {  @Override  public void onAnimationStart(Animator animation) {  isLtr = !isLtr;  }  @Override  public void onAnimationRepeat(Animator animation) {  isLtr = !isLtr;  }  @Override  public void onAnimationCancel(Animator animation) {  isAnimCanceled = true;  }  @Override  public void onAnimationEnd(Animator animation) {  if (!isAnimCanceled) {   anim.start();  }  } }); }

代码中看到,如果小球一次移动后不需要停顿(pauseDuration = 0),那么直接通过anim.setRepeatCount(ValueAnimator.INFINITE)让动画无限循环,否则的话就要通过anim.setStartDelay(pauseDuration)来设置停顿时间,然后在监听的onAnimationEnd里重启动画,以此实现每一次移动后小球能停顿一定时间。在onAnimationUpdate里,我们记录了当前动画百分比fraction,然后通过invalidate()重绘,在之后的onDraw里将通过该值画出小球。另外,每次动画开始时(或是重复时),会将isLtr取反,这个标志位的作用是标明当前哪颗球在【从左往右】移动,因为两颗球的颜色、初始半径是不一样的嘛,onDraw里画小球时是需要这个标志位协助的。

有了动画进度fraction和标志位isLtr后,就可以在onDraw里画出小球了。

**首先要计算小球当前的坐标**。y坐标永远是固定的,不谈,x坐标随着`fraction`的变化而变化。两颗球之间最远距离为球1半径+球2半径+两球间隔,即`distance = gap + radius1 + radius2;`,这个值就是两颗球的移动范围,由此可计算出,当前【从左往右】移动的小球的x坐标和当前【从右往左】移动的小球x坐标分别为:

float ltrX = getMeasuredWidth() / 2.0f - distance / 2.0f;ltrX = ltrX + (distance * fraction);float rtlX = getMeasuredWidth() / 2.0f + distance / 2.0f;rtlX = rtlX - (distance * fraction);

**接下来要计算小球当前的大小**。小球的大小也是随着动画进度变化的,上面已经说明了`scaleStartFraction`和`scaleEndFraction`属性的含义。 以当前小球【从左往右】移动为例,当动画进度为0时,小球大小为初始1倍大小;当动画进度到scaleStartFraction时,小球大小将缩放到`ltrScale`倍,当动画进度为[scaleStartFraction,scaleEndFraction]范围时,小球大小保持`ltrScale`倍,当动画进度到[scaleEndFraction,1]范围时,小球则从`ltrScale`倍逐渐恢复至1倍。 为了便于计算,首先将`[0,scaleStartFraction]`转换为`[0,1.0]`的真实百分比,根据`y = kx + b`(就这么个入门公式。。我都要在纸上算一遍T-T),可以得出:`float scaleFraction = 1.0f / scaleStartFraction * fraction; `,有了这个真实百分比,那么该区间里小球当前半径就好计算了:

ltrBallRadius = ltrInitRadius * (1 + (ltrScale - 1) * scaleFraction);rtlBallRadius = rtlInitRadius * (1 + (rtlScale - 1) * scaleFraction);

应该好懂的吧。另外[scaleEndFraction,1]区间里小球当前半径计算思路是一样的,不谈。

最后就是要画出小球。这里主要是如何画出实现两球叠加的部分的颜色。

思路1:通过xfermode方式实现:

从上图可以看出用Darken、Lighten、Screen模式可以做到让叠加处上色,但是颜色不能自定义。

思路2:通过path的OP操作实现(API19):

(图片摘自http://www.gcssloop.com/customview/Path_Over)

因此,可以先构造两个小球的Path,然后再将这两个Path进行INTERSECT操作,即可获得叠加处的Path,这样就可以做到自定义叠加处的颜色了。

onDraw完整代码:

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float centerY = getMeasuredHeight() / 2.0f; float ltrInitRadius, rtlInitRadius; Paint ltrPaint, rtlPaint; //确定当前【从左往右】移动的是哪颗小球 if (isLtr) {  ltrInitRadius = radius1;  rtlInitRadius = radius2;  ltrPaint = paint1;  rtlPaint = paint2; } else {  ltrInitRadius = radius2;  rtlInitRadius = radius1;  ltrPaint = paint2;  rtlPaint = paint1; } float ltrX = getMeasuredWidth() / 2.0f - distance / 2.0f; ltrX = ltrX + (distance * fraction);//当前从左往右的球的X坐标 float rtlX = getMeasuredWidth() / 2.0f + distance / 2.0f; rtlX = rtlX - (distance * fraction);//当前从右往左的球的X坐标 //计算小球移动过程中的大小变化 float ltrBallRadius, rtlBallRadius; if (fraction <= scaleStartFraction) { //动画进度[0,scaleStartFraction]时,球大小由1倍逐渐缩放至ltrScale/rtlScale倍  float scaleFraction = 1.0f / scaleStartFraction * fraction; //百分比转换 [0,scaleStartFraction]] -> [0,1]  ltrBallRadius = ltrInitRadius * (1 + (ltrScale - 1) * scaleFraction);  rtlBallRadius = rtlInitRadius * (1 + (rtlScale - 1) * scaleFraction); } else if (fraction >= scaleEndFraction) { //动画进度[scaleEndFraction,1],球大小由ltrScale/rtlScale倍逐渐恢复至1倍  float scaleFraction = (fraction - 1) / (scaleEndFraction - 1); //百分比转换,[scaleEndFraction,1] -> [1,0]  ltrBallRadius = ltrInitRadius * (1 + (ltrScale - 1) * scaleFraction);  rtlBallRadius = rtlInitRadius * (1 + (rtlScale - 1) * scaleFraction); } else { //动画进度[scaleStartFraction,scaleEndFraction],球保持缩放后的大小  ltrBallRadius = ltrInitRadius * ltrScale;  rtlBallRadius = rtlInitRadius * rtlScale; } ltrPath.reset(); ltrPath.addCircle(ltrX, centerY, ltrBallRadius, Path.Direction.CW); rtlPath.reset(); rtlPath.addCircle(rtlX, centerY, rtlBallRadius, Path.Direction.CW); mixPath.op(ltrPath, rtlPath, Path.Op.INTERSECT); canvas.drawPath(ltrPath, ltrPaint); canvas.drawPath(rtlPath, rtlPaint); canvas.drawPath(mixPath, mixPaint); }

以上就是"Android中怎么实现两颗小球转动效果"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

小球 动画 移动 大小 进度 半径 坐标 颜色 效果 属性 百分 百分比 范围 叠加 就是 思路 知识 篇文章 变化 标志 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网是不是新科技 互联网科技公司电话 亿策互联网科技 苏州互联网科技贷款公司 壕鑫互联网络科技 互联网科技股有哪些 上海电发互联网科技有限公司 互联网经济与金融科技 互联网科技产业特征 玉溪互联网科技怎么选 四川慕妮娅互联网科技有限公司 张召忠谈中国互联网科技 下一代互联网重大应用科技园 济南小医互联网科技有限公司招聘 吉林省码上互联网科技电话 互联网时代科技型公司的机会 互联网科技品牌 亚光科技低轨卫星互联网 杭州科技互联网公司有哪些 互联网科技创新方面的资料 互联网科技的英文 致聘互联网科技 智慧科技互联网 四川狮子座互联网科技 互联网科技公司做什么 宁夏众和广鑫互联网科技有限公司 中和天地互联网科技有限公司 从那以后互联网科技有限公司 工业互联网科技成果转化 宁波跨境商互联网科技有限公司
0