//绘制旋转了指定角度的唱针private void drawNeedle(Canvas canvas,int degree){//移动坐标到水平中点canvas.save();canvas.translate(halfMeassuredWidth,0);//绘制唱针手臂needPaint.setStrokeWidth(20);needPaint.setColor(Color.parseColor("#C0C0C0"));//绘制第一段臂canvas.rotate(degree);canvas.drawLine(0,0,0,longArmLength,needPaint);//绘制第二段臂canvas.translate(0,longArmLength);canvas.rotate(-30);canvas.drawLine(0,0,0,shortArmLength,needPaint);//绘制唱针头//绘制第一段唱针头canvas.translate(0,longHeadLength);needPaint.setStrokeWidth(40);canvas.drawLine(0,0,0,longHeadLength,needPaint);//绘制第二段唱针头canvas.translate(0,longHeadLength);needPaint.setStrokeWidth(60);canvas.drawLine(0,0,0,shortHeadLength,needPaint);canvas.restore();//两个重叠的圆形canvas.save();canvas.translate(halfMeassuredWidth,0);needPaint.setStyle(Paint.Style.FILL);needPaint.setColor(Color.parseColor("#C0C0C0"));canvas.drawCircle(0,0,bigCircleRadius,needPaint);needPaint.setColor(Color.parseColor("#8A8A8A"));canvas.drawCircle(0,0,samllCircleRadius,needPaint);canvas.restore();}
public class GramophoneView extends View{private int halfMeassuredWidth;// 绘制唱片相关变量private static final int DEFAULT_PICTURE_RADIUS = 400;// 中间图片默认半径private static final float DEFAULT_DISK_ROTATE_SPEED = 0.3f;  // 唱片旋转默认速度,其实是通过每次旋转叠加的角度来控制速度private int pictureRadius;  //中间图片的半径private int ringWidth;  //黑色圆环宽度private float diskRotateSpeed;  //唱片旋转速度private Paint discPaint;  //唱片画笔private Path clipPath; //裁剪图片的路径private Bitmap bitmap;  //图片private Rect srcRect;  //图片被裁剪范围private Rect dstRect;  //图片被绘制范围private static final int PLAY_DEGREE  = -15;//播放状态唱针的旋转角度private static final int PAUSE_DEGREE = -45;//暂停状态唱针的旋转角度private int samllCircleRadius = 20;//唱针顶部小圆半径private int bigCircleRadius;//唱针顶部大圆半径private int longArmLength; //唱针手臂,较长那段的长度private int shortArmLength; //唱针手臂,较短那段的长度private int longHeadLength; //唱针的头,较长那段的长度private int shortHeadLength; //唱针的头,较短那段的长度private Paint needPaint;  //唱针画笔private boolean isPlaying; //是否处于播放状态private int needleDegreeCounter; //唱针旋转角度计数器private float diskDegreeCounter; //唱片旋转角度计数器public GramophoneView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GramophoneView);pictureRadius = (int) typedArray.getDimension(R.styleable.GramophoneView_picture_radius,DEFAULT_PICTURE_RADIUS);diskRotateSpeed = typedArray.getFloat(R.styleable.GramophoneView_disk_rotate_speed,DEFAULT_DISK_ROTATE_SPEED);Drawable drawable = typedArray.getDrawable(R.styleable.GramophoneView_src);if (drawable==null){bitmap =  BitmapFactory.decodeResource(getResources(),R.mipmap.gramophone_view_default_picture);}else {bitmap = ((BitmapDrawable)drawable).getBitmap();}typedArray.recycle();//初始化唱片变量ringWidth = pictureRadius>>1;discPaint = new Paint();discPaint.setColor(Color.BLACK);discPaint.setStyle(Paint.Style.STROKE);discPaint.setStrokeWidth(ringWidth);srcRect = new Rect();dstRect = new Rect();setBitmapRect(srcRect,dstRect);clipPath = new Path();clipPath.addCircle(0,0,pictureRadius,Path.Direction.CW);diskDegreeCounter = 0;//初始化唱针变量bigCircleRadius = samllCircleRadius<<1;shortHeadLength = (pictureRadius + ringWidth)/15;longHeadLength = shortHeadLength<<1;shortArmLength = longHeadLength<<1;longArmLength = shortArmLength<<1;needPaint = new Paint();needleDegreeCounter = PAUSE_DEGREE;}
}
//绘制旋转了指定角度的唱片(类似唱针,唱片里面的图片是会旋转不同角度的)private void drawDisk(Canvas canvas,float degree){//移动坐标系到唱针下方合适位置,然后旋转指定角度//save():用来保存Canvas的状态,save()方法之后的代码,能够调用Canvas的平移、放缩、旋转、裁剪等操作!canvas.save();canvas.translate(halfMeassuredWidth,pictureRadius+ringWidth+longArmLength);canvas.rotate(degree);//绘制圆环canvas.drawCircle(0,0,pictureRadius+ringWidth/2,discPaint);//绘制图片canvas.clipPath(clipPath);canvas.drawBitmap(bitmap,srcRect,dstRect,discPaint);canvas.restore();//.restore():用来恢复Canvas之前保存的状态,防止save()方法代码之后对Canvas运行的操作。继续对兴许的绘制会产生影响。通过该方法能够避免连带的影响!}
 @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);halfMeassuredWidth = getMeasuredWidth()>>1;drawDisk(canvas);//绘制唱片drawNeedle(canvas);//绘制唱针// 如果唱针当前角度大于暂停状态下的角度(注意了由于是负数所以是大于),// 继续重绘if (needleDegreeCounter > PAUSE_DEGREE){invalidate();}}//绘制唱片(胶片)private void drawDisk(Canvas canvas) {// 这里的diskRotateSpeed变量就是唱片每次变化角度,就是旋转速度的意思diskDegreeCounter = diskDegreeCounter%360 + diskRotateSpeed;drawDisk(canvas,diskDegreeCounter);}private void drawNeedle(Canvas canvas) {//根据播放/暂停状态控制唱针角度的加/减变化if(isPlaying){if (needleDegreeCounter < PLAY_DEGREE){needleDegreeCounter += 3;Log.e("zhangyubin",needleDegreeCounter+"");}}else {if (needleDegreeCounter >PAUSE_DEGREE){needleDegreeCounter -=3;Log.e("zhangyubin",needleDegreeCounter+"");}}drawNeedle(canvas,needleDegreeCounter);}

自定义View实现网易云音乐留声机效果(代码区)相关推荐

  1. Android自定义View——仿网易云音乐留声机效果

    //自定义类 public class GramophoneView extends View {/*** 尺寸计算设计说明:* 1.唱片有两个主要尺寸:中间图片的半径.黑色圆环的宽度.* 黑色圆环的 ...

  2. android bitmap转图片_带你用Android自定义View实现网易云音乐宇宙尘埃特效

    作者:Mlx, 链接:https://juejin.im/post/6871049441546567688 前言 前段时间,女朋友用网易云音乐的时候看到一个宇宙尘埃特效,说很好看,想要让我给她开VIP ...

  3. Android自定义View分享——仿网易云音乐留声机效果

    写在前面 这是笔者自学习自定义View以来,分享的第五篇效果,之前分享过一篇动态时钟效果的自定义View,如果有兴趣的可以看看: Android自定义View分享--一个时钟 之前的博客笔者一般都会说 ...

  4. 自定义View之网易云音乐听歌识曲水波纹动画

    先上效果图 点击中间的按钮后,像外发散水波纹,再次点击水波纹消失. 实现原理 当点击按钮后,我们隔一段时间执行一个RippleCircleView的动画,动画包括扩大和透明度,通过PropertyVa ...

  5. Android自定义view之网易云推荐歌单界面

    系列文章目录 Android自定义view之网易云推荐歌单界面 文章目录 系列文章目录 前言 一.实现 1.自定义一个圆角图片控件(也可直接使用第三方框架) 2.进行布局摆设 3.图片切换动画效果 二 ...

  6. 矿小助 全局主题 | 一个插件实现网易云音乐主题效果 | Flutter

    矿小助拥有三种主题,实现起来非常复杂,总结起来就更不用说了,头皮发麻QAQ. 因此,花了半天时间将其拆分出来,做成插件,开源给大家使用.具体的细节大家自己研究吧(溜). 第一次做插件,难免考虑不周,还 ...

  7. Android漂亮的音乐歌词控件,仿网易云音乐滑动效果

    前言: 项目有个音乐播发器功能,实现音乐在线播放,同时需要带有歌词显示功能.网上也找过,在github找到勉强能用的控件,只是效果还是差强人意,不是特别好.于是趁有空的时间,参考了网上的部分demo, ...

  8. 自定义插件实现网易云音乐首页图片轮播

    编写html界面 <!DOCTYPE html> <html><head><meta charset="utf-8" /><t ...

  9. HTML网页调用 网易云 音乐播放器代码

    表现形式一:单曲播放 调用代码: <iframe frameborder="no" border="0" marginwidth="0" ...

最新文章

  1. 领域驱动设计(DDD:Domain-Driven Design)
  2. redis三种架构:主从Cluster哨兵+整合Springboot访问redis
  3. SQL中binary 和 varbinary的区别
  4. SDUT 2603:Rescue The Princess
  5. boot客户管理系统环境的搭建_LANIF Admin开源免费后台管理系统(React)
  6. C语言冒泡排序三种写法,冒泡排序的三种实现方法
  7. 【Excel2019(六):数据透视表】【创建数据透视表+更改数据透视表汇总方式+数据透视表中的组合+汇总多列数据+创建计算字段+生成多张工作表】
  8. 关于KEILC51和KEILMDK的合并
  9. 2022计算机二级全套资料:视频+练习软件+真题资料
  10. 深入解读云场景下的网络抖动
  11. Response.addHeader()和Response.setHeader()的区别,别再傻傻分不清;
  12. 华为鸿蒙系统操作教程_华为鸿蒙系统2.0怎么安装 鸿蒙系统2.0安装教程[多图]
  13. SpringBoot框架中的DAO(mapper)层、Entity层、Service层、Controller层
  14. EOS是什么以及含义
  15. Linux学习-redis主从架构
  16. Anemometer使用详解
  17. 五招祛痘法让熟女远离痘痘 - 健康程序员,至尚生活!
  18. 麦肯锡精英高效读书法心得
  19. 国务院将灵活就业列入“放管服”重点任务分工方案
  20. scrapy-爬取百度贴吧之物流内容。

热门文章

  1. 数字人民币究竟是什么
  2. HDInsight 简介
  3. “人体内物质的运输及废物的排出”复习课教学心得
  4. ASP.NET Web Forms 转换至MVC开发
  5. 雨林木风高仿真XP发布
  6. 《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day5
  7. 医疗信息系统HIS如何配置短信提醒?
  8. Android 条码扫描
  9. SpringBoot thymeleaf页面下拉框使用枚举类
  10. ubuntu修改网卡名称