穿插一篇自定义view 的动画效果,偶然看到的一个gif刷新齿轮效果图片,原图如下:

感觉挺有意思的,就想自己也做一个,发费了一番功夫,算是做出了基本效果,但原谅我使其美观尽毁,做出的效果如下:

gif录制有些掉帧

好了,放源码了:

public class GearView extends View {private Context context;private Paint paint;private float PI = 3.1415926f;private int circleGrade = 1;//圆的齿轮个数 9+circleGrade 个private float gearWidth = 40;private float gearHeight = 50;private float length = 60;//弧长private List<Circle> circles;//存储圆的参数private Map<Float, Bitmap> bitmaps;//把已经绘制好的bitmap存储起来,循环利用private int speedArgu = 20;//旋转速度参数private int viewWidth;//所在view 的宽度private int viewHeight;//所在view 的高度private boolean startRotato = true;//是否开始动画private int r1;private int r2;private int r3;private int r4;private int r5;private float fTran = 0;//平移基本数private float translationArgu = 4.0f;//平移乘数private float fRotate = 0;//平移后中心旋转基本数private float transientRotate = 70.0f;//平移后中心旋转乘数private float scale = 0.001f;//平移后中心缩放 程度private float scaleBase = 1.0f;//平移后中心缩放基本数public boolean isStartRotato() {return startRotato;}public void setStartRotato(boolean startRotato) {this.startRotato = startRotato;}public int getSpeedArgu() {return speedArgu;}public void setSpeedArgu(int speedArgu) {if(speedArgu > 70){speedArgu = 70;}if(speedArgu < 5 && speedArgu > 0){speedArgu = 5;}if(speedArgu < -70){speedArgu = -70;}if(speedArgu <0 && speedArgu > -5){speedArgu = -5;}this.speedArgu = speedArgu;}public GearView(Context context) {super(context);this.context = context;init();}public GearView(Context context, AttributeSet attrs) {super(context, attrs);context = context;init();}public GearView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);context = context;init();}private void init() {paint = new Paint();paint.setAntiAlias(false);bitmaps = new HashMap<Float, Bitmap>();circles = new ArrayList<Circle>();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);this.viewHeight = h;this.viewWidth = w;initCircle();}private void initCircle() {float centerX = viewWidth/2;float centerY = viewHeight/2;//添加圆和设置位置,在此处添加和修改即可r1 = 3;
//        float c1Top = centerY-getRaidus(r1) * 2;float c1Top = centerY-getRaidus(r1) -20;float c1Left = centerX-getRaidus(r1) * 2;int color1 = getResources().getColor(R.color.colorGear1);Circle circle = new Circle(c1Top,c1Left,getRaidus(r1), false,0,0,color1);circles.add(circle);r2 = 8;updataHeight(r2);float c2Top = c1Top + getRaidus(r2) + gearHeight;float c2Left = c1Left - getRaidus(r2) - gearHeight;int color2 = getResources().getColor(R.color.colorGear2);circle = new Circle(c2Top ,c2Left, getRaidus(r2), true,0,3, color2);circles.add(circle);r3 = 18;updataHeight(r3);float c3Top = c2Top - getRaidus(r3) -getRaidus(r2) - gearHeight + 5;float c3Left = c2Left - getRaidus(r3) - getRaidus(r2)- gearHeight + 5;int color3 = getResources().getColor(R.color.colorGear3);circle = new Circle(c3Top ,c3Left, getRaidus(r3), false,0,6, color3);circles.add(circle);r4 = 11;updataHeight(r4);float c4Top = c1Top - getRaidus(r4) - gearHeight - getRaidus(r1);float c4Left = c1Left + getRaidus(r4) + gearHeight - getRaidus(r1);int color4 = getResources().getColor(R.color.colorGear4);circle = new Circle(c4Top ,c4Left, getRaidus(r4), true,0,-5, color4);circles.add(circle);r5 = 16;updataHeight(r5);float c5Top = c4Top  +getRaidus(r5) + gearHeight + 10 ;float c5Left = c4Left  + getRaidus(r5)+ gearHeight +10 ;int color5 = getResources().getColor(R.color.colorGear5);circle = new Circle(c5Top ,c5Left, getRaidus(r5), false,0,2, color5);circles.add(circle);}/*** 供外部调用旋转* */public void startRotato(float dy){int speed = (int) (dy * 4);setSpeedArgu(speed);startRotato = true;isTranslation = false;if((speed < 20 && speed >0) || (speed < 0 && speed > -20)){speed = 20;}if(speed <= -20){speed = Math.abs(speed);}if(speed > 100 || speed < -100){speed = 100;}for(int i = 0;i<speed;i++){invalidate();}}public void stopRotato(){startRotato = false;}public void startTranslation(){isTranslation = true;startRotato = false;invalidate();}/*** 返回初始化* */public void  backInit(){isTranslation = false;startRotato = false;fTran = 0;bitmaps.clear();circles.clear();initCircle();}private boolean isTranslation = false;@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(this.getResources().getColor(R.color.colorFefreshBg));if(isTranslation){translationCircles(canvas);invalidate();}if(startRotato){for (Circle circle : circles) {drawCircle(canvas, circle);}
//            invalidate();}}/*开展平移动画*/private void translationCircles(Canvas canvas) {if(bitmaps == null || bitmaps.size() <5){return;}Bitmap bitmap = bitmaps.get(getRaidus(r1));Matrix matrix = new Matrix();int offsetX = bitmap.getWidth() / 2;int offsetY = bitmap.getHeight() / 2;matrix.postTranslate(-offsetX, -offsetY);Circle circle = circles.get(0);circle.setClockwise(true);fRotate = fRotate + (0.1f * transientRotate);matrix.postRotate(fRotate);scale+= 0.001f;if(scale < 0.01f){scaleBase += scale;}if(scale >0.01f && scale <0.03f){scaleBase = scaleBase -scale +0.01f;}matrix.postScale(scaleBase,scaleBase);matrix.postTranslate(circle.getLeft() + offsetX, circle.getTop() + offsetY);canvas.drawBitmap(bitmap,matrix,null);fTran+=1.0f * translationArgu;Bitmap bitmap1 = bitmaps.get(getRaidus(r2));Matrix matrix1 = new Matrix();Circle circle1 = circles.get(1);matrix1.postTranslate(circle1.getLeft()-fTran,circle1.getTop()+fTran);canvas.drawBitmap(bitmap1,matrix1,null);Bitmap bitmap2 = bitmaps.get(getRaidus(r3));Matrix matrix2 = new Matrix();Circle circle2 = circles.get(2);matrix2.postTranslate(circle2.getLeft()-fTran,circle2.getTop()-fTran);canvas.drawBitmap(bitmap2,matrix2,null);Bitmap bitmap3 = bitmaps.get(getRaidus(r4));Matrix matrix3 = new Matrix();Circle circle3 = circles.get(3);matrix3.postTranslate(circle3.getLeft()+fTran,circle3.getTop()-fTran);canvas.drawBitmap(bitmap3,matrix3,null);Bitmap bitmap4 = bitmaps.get(getRaidus(r5));Matrix matrix4 = new Matrix();Circle circle4 = circles.get(4);matrix4.postTranslate(circle4.getLeft()+fTran,circle4.getTop()+fTran);canvas.drawBitmap(bitmap4,matrix4,null);}/*绘制圆的动画效果*/private void drawCircle(Canvas canvas, Circle circle) {float top = circle.getTop();float left = circle.getLeft();float radius = circle.getRaidus();boolean isClockwise = circle.isClockwise();float speed = circle.getSpeed();canvas.drawColor(Color.TRANSPARENT);Paint paint = new Paint(this.paint);paint.setColor(Color.YELLOW);Bitmap trapezoidBitmap = getTrapezoidBitmap(circle, paint);Matrix matrix = new Matrix();int offsetX = trapezoidBitmap.getWidth() / 2;int offsetY = trapezoidBitmap.getHeight() / 2;matrix.postTranslate(-offsetX, -offsetY);if (isClockwise) {matrix.postRotate(speed+circle.getStartDegree());} else {matrix.postRotate(-speed+circle.getStartDegree());}float degree = getDegree(0.1f * speedArgu, radius);speed += degree;circle.setSpeed(speed);matrix.postTranslate(left + offsetX, top + offsetY);canvas.drawBitmap(trapezoidBitmap, matrix, null);}/*绘制圆*/private Bitmap getTrapezoidBitmap(Circle circle, Paint paint) {float radius = circle.getRaidus();if(bitmaps == null){bitmaps = new HashMap<Float, Bitmap>();}Bitmap bitmap = bitmaps.get(radius);if (bitmap != null) {return bitmap;}Bitmap bitmapTmp = Bitmap.createBitmap((int) (radius * 2 + gearHeight * 2), (int) (radius * 2 + gearHeight * 2), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmapTmp);canvas.drawColor(Color.TRANSPARENT);canvas.translate(bitmapTmp.getWidth() / 2, bitmapTmp.getHeight() / 2);/* 设置渐变色  *//*Shader mShader = new LinearGradient(0, 0, 100, 100,new int[]{Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW,Color.LTGRAY}, null, Shader.TileMode.REPEAT); // 一个材质,打造出一个线性梯度沿著一条线。paint.setShader(mShader);*/paint.setColor(circle.getColor());canvas.drawCircle(0, 0, radius, paint);drawGear(canvas,circle, paint);bitmaps.put(radius,bitmapTmp);return bitmapTmp;}/*在圆上画齿轮*/private void drawGear(Canvas canvas, Circle circle, Paint paint) {updataHeight(circle.getRaidus());float radius = circle.getRaidus();Path path = new Path();path.moveTo(-(gearWidth / 2), -radius + 5);path.lineTo(gearWidth / 2, -radius + 5);path.lineTo(gearWidth / 2 - 10, -radius - gearHeight + 10);path.lineTo(-(gearWidth / 2 - 10), -radius - gearHeight + 10);path.lineTo(-(gearWidth / 2), -radius + 5);int num = (int) (360 / getDegree(length, radius));Paint p = new Paint(paint);p.setColor(circle.getColor());for (int i = 0; i <= num; i++) {canvas.drawPath(path, p);canvas.rotate(getDegree(length, radius));}canvas.save();}private void updataHeight(float radius) {gearHeight = radius/4f;if(gearHeight<35){gearHeight = 35;} else if(gearHeight > 50){gearHeight = 50;}}/*** 由弧长获取度数*/public float getDegree(float length, float r) {float degree = 360 * length / (2 * PI * r);return degree;}public float getPerimeter(float r) {float perimeter = 2 * PI * r;return perimeter;}/*** 对圆的半径有要求** @param multiple* @return*/public float getRaidus(int multiple) {int gearNum = 5;gearNum += multiple;//gearNum代表圆上齿轮的个数float f1 = length * gearNum;float f = f1 / (2 * PI);return f;}public void setGear(int gear) {gearHeight = gearHeight + gear*3;}class Circle {float top;//顶部坐标float left;//左侧坐标float raidus;//半径float speed;//旋转速度boolean clockwise;//旋转方向float gearWidth;float gearHeight;float startDegree;//起始角度private int color;public int getColor() {return color;}public void setColor(int color) {this.color = color;}public float getStartDegree() {return startDegree;}public void setStartDegree(float startDegree) {this.startDegree = startDegree;}public float getGearWidth() {return gearWidth;}public void setGearWidth(float gearWidth) {this.gearWidth = gearWidth;}public float getGearHeight() {return gearHeight;}public void setGearHeight(float gearHeight) {this.gearHeight = gearHeight;}public Circle(float top, float left, float raidus, boolean clockwise, float speed, float startDegree, int color) {this.left = left;this.top = top;this.raidus = raidus;this.clockwise = clockwise;this.speed = speed;this.startDegree = startDegree;this.color = color;}public boolean isClockwise() {return clockwise;}public void setClockwise(boolean clockwise) {this.clockwise = clockwise;}public float getTop() {return top;}public void setTop(float top) {this.top = top;}public float getLeft() {return left;}public void setLeft(float left) {this.left = left;}public float getRaidus() {return raidus;}public void setRaidus(float raidus) {this.raidus = raidus;}public float getSpeed() {return speed;}public void setSpeed(float speed) {this.speed = speed;}}}

RecycleView刷新 齿轮转动动画效果相关推荐

  1. HTML绘制齿轮,使用css3制作齿轮loading动画效果

    HTML 首先在页面中引入font-awesome文件. 然后在放置动画的位置加上HTML结构: CSS样式 然后通过下面的CSS样式来制作齿轮的动画效果. #loader-wrapper { wid ...

  2. iOS 实现下拉刷新gif实时动画效果

    最近看到很多app下拉刷新的酷炫效果,图片伴随下拉高度逐帧变化的那种效果.查了很多资料,还是找不到这样的效果demo...不过也找到一个通过计算高度画线的线条动画来实现的demo,这个效果也是非常不错 ...

  3. echarts 数据重置图表刷新,带动画效果刷新

    1.数据源更新,图表刷新,带动画 const myChart = this.$echarts.init(_id); myChart.clear(); myChart.setOption(option, ...

  4. ios微信小程序下拉刷新怎么配_为什么他的下拉刷新是个动画效果?

    看到别人的下拉刷新动画!是不是蠢蠢欲动!也想马上拥有一个~~ 比如: 再比如: "小二,上菜!" 1            引入下拉刷新组件(组件代码可联系作者获取)  代码:  ...

  5. html滚轮下拉动画,html5+css3齿轮滚动动画代码

    HTML5制作齿轮滚动动画效果. 文件引用: setInterval(function () { move('.sec4-img-1').set('bottom', '300px').set('opa ...

  6. 实现齿轮转动动画CSS3特效

    CSS3实现齿轮转动动画特效, css3   齿轮转动,动画效果,CSS3实现齿轮转动动画特效 是一款CSS3结合图片实现的机械齿轮连接转动的CSS3特效代码. 下载地址:http://www.hui ...

  7. android下拉刷新动画效果代码_vue项目实录:下拉刷新组件的开发及slot的使用

    "下拉刷新"和"上滑加载更多"功能在前端.尤其是移动端项目中非常重要,这里笔者由曾经做过的vue项目中的"blink"功能和各位探讨下[下拉 ...

  8. android 自定义刷新控件,Android开发中MJRefresh自定义刷新动画效果

    有时候我们对自己开发的项目经常不满意,但是我们要达到自定义刷新动画的效果有一定的难度,别着急,下面爱站技术频道和大家分享Android开发中MJRefresh自定义刷新动画效果,一起来学习吧! [一] ...

  9. iOS 类似亲宝宝app下拉刷新动画效果

    iOS 类似亲宝宝app下拉刷新动画效果,最近看了下这种效果,感觉有点意思.于是就实现了一下. 方案一 采用两个背景View1.View2,三个球ball1,ball2,ball3,将ball1,ba ...

最新文章

  1. php语言出现弹框 再提交怎么写,jquery/php和多语言确认/警报框
  2. 智能车竞赛技术报告 | 智能车视觉 - 武汉理工大学 - WHY
  3. 【Origin】晨起忆梦
  4. IDEA之过滤那些不重要的文件
  5. CodeForces 474.D Flowers
  6. html图片渐隐渐显,js实现图片切换效果渐隐渐显
  7. Xilinx+AWS F1+VP9带来30倍实时转码性能提升
  8. testng.xml文件配置
  9. html5游戏制作入门系列教程(六)
  10. python中奖号_Python分析彩票记录并预测中奖号码过程详解
  11. 一个简易的数字输入框组件
  12. JavaScript事件监听完整实例(含注释)
  13. c语言编程车,C语言编程之自动类型转化
  14. Atitit 图像处理 公共模块 矩阵扫描器
  15. 学习PLC编程必须要知道的小常识,一起学起来
  16. CentOS安装jre环境
  17. 计算机图形学(九)-纹理的应用,环境贴图、凹凸贴图、法线贴图、位移贴图
  18. SSM开发书评网25:写短评;
  19. 公众号平台服务号、订阅号、企业号区别
  20. 10.数据库恢复技术

热门文章

  1. pyqt5 时间控件设为当前日期
  2. 简易词典Android界面代码,Android 有道词典的简单实现方法介绍
  3. React Demo Three - 简书掘金
  4. 天荒地老修仙功-第六部:Spring Cloud Eureka——服务发现
  5. layui数据表格自定义数据项
  6. 解决 ERROR 1044 (42000): Access denied for user ‘‘@‘localhost‘ to database ‘mysql‘
  7. windows系统运维基础
  8. 微信小程序实现预览图片
  9. 十五、2021-11-16Hadoop集群问题记录
  10. 青龙 金手指教程每天低保保姆安装教程