自定义网易云播放页面

首先我们先来看看最终的效果

在这里插入图片描述

现在我们来一步一步实现这个效果

  1. 首先我们先自定义VIew,把唱片背景图画上去,代码很简单
  • 定义一个Bitmap变量,保存唱片图片,在初始化方法中获取唱片图片
//获取唱片图片Bitmap
discBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.play_page_disc);
//转换图片大小
discBitmap = ImageUtils.resizeImage(discBitmap, (int) (Util.getScreenWidth(getContext()) * 0.75), (int) (Util.getScreenWidth(getContext()) * 0.75));
  • 在View的onDraw方法中绘制图片
//绘制唱片图片
canvas.drawBitmap(discBitmap,0,0,null);
  • 现在运行我们来看看效果
    在这里插入图片描述
  • 图片没有居中,我们把它居中起来
    定义图片的Matrix和Point
	private Matrix discMatrix = new Matrix();//唱片图片的Matrix对象,此处使用Matrix,方便后面做旋转功能
    private Point discPoint = new Point();//唱片图片的位置

定义初始化位置的方法,在自定义View的onLayout()中调用

 	/**
     * 初始化位置
     */
    private void initSize() {
        //唱片图片的位置
        discPoint.x = (getWidth() - discBitmap.getWidth()) / 2;
    }

修改我们的绘制方法

 	discMatrix.preTranslate(discPoint.x, 0f); //图片居中
    //绘制唱片图片
    canvas.drawBitmap(discBitmap, discMatrix, null);
  • 现在我们再来看看运行效果,可以看到图片已经居中啦在这里插入图片描述
  • 下一步我们让图片旋转起来
    Matrix的setRotate(float degrees, float px, float py)的方法可以旋转图片,参数分别为旋转角度,旋转中心点X轴值和旋转中心点Y轴的值
    我们可以定义一个变量保存旋转的角度,使用一个定时器不断的改变这个值,然后重绘页面,就可以使图片不停的旋转起来啦
 	private float discRotation = 0.0f;//唱片图片和中心歌曲海报旋转的角度,
    private static final float DISC_ROTATION_INCREASE = 0.5f;//每次旋转的角度

在画图片的时候,把设置图片的旋转中心和旋转角度,注意此处要放在图片居中的前面,且要使用setRotate()方法

 	 //图片旋转
    discMatrix.setRotate(discRotation, discCenterPoint.x, discCenterPoint.y);
 	    /**
     * 创建一个定时任务,定时改变图片的选择角度
     */
    private Runnable rotationRunnable = new Runnable() {
        @Override
        public void run() {
            discRotation += DISC_ROTATION_INCREASE;
            if (discRotation >= 360) {
                discRotation = 0;
            }
            //通知页面重绘
            invalidate();
            myHandler.postDelayed(this, TIME_UPDATE);
        }
    };
 	/**
     * 开始播放
     */
    public void startPlay() {
        if (isPlaying) {
            return;
        }
        isPlaying = true;
        //启动定时器,执行旋转动画
        myHandler.post(rotationRunnable);
    }
  • 由于只有一个唱片图片,旋转起来不能明细看到效果,我们现在来添加歌曲封面图片
    首先定义封面图片和位置对象
 	private Bitmap coverBitmap;//歌曲封面图片
    private Matrix coverMatrix = new Matrix();//封面图片的Matrix
    private Point coverPoint = new Point();//封面图片的位置

初始化图片

 	//获取封面图片Bitmap
    coverBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.cover);
   //转换图片大小
 coverBitmap=ImageUtils.resizeImage(coverBitmap,Util.getScreenWidth(getContext()) / 2,Util.getScreenWidth(getContext()) / 2);
   //将图片剪裁为圆形
   coverBitmap = ImageUtils.createCircleImage(coverBitmap);

设置位置

 	//封面图片的位置
    coverPoint.x = (getWidth() - coverBitmap.getWidth()) / 2;
    coverPoint.y = (discBitmap.getHeight() - coverBitmap.getHeight()) / 2;

绘制图片,此处旋转图片的参数可以直接使用唱片图片的

 	//图片旋转
    coverMatrix.setRotate(discRotation, discCenterPoint.x, discCenterPoint.y);
    //图片位置
    coverMatrix.preTranslate(coverPoint.x, coverPoint.y);
    //绘制封面图片
    canvas.drawBitmap(coverBitmap, coverMatrix, null);
  • 现在我们再来看看效果
    在这里插入图片描述

  • 好了,到现在我们已经实现主要功能啦,下一步我们来添加右上角的指针图片
    和原来一样,添加存储图片位置等数据的变量

 	private Bitmap needleBitmap;//指针图片
    private Matrix needleMatrix = new Matrix();//指针图片的Matrix
    private Point needlePoint = new Point();//指针图片的位置

初始化图片

 //获取指针图片Bitmap
 needleBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.play_page_needle);
 //转换图片大小
 needleBitmap = ImageUtils.resizeImage(needleBitmap, (int) (Util.getScreenWidth(getContext()) * 0.25),
                (int) (Util.getScreenWidth(getContext()) * 0.375));

设置位置,

 //指针图片的位置
  needlePoint.x = (getWidth() - needleBitmap.getWidth()) / 2 +100;

**此处注意,指针图片在唱片图和封面图片的上面,所以唱片图片和封面图片的高度需要调整,需要加上 指针图片的高度 / 2 **

 int discOffsetY = needleBitmap.getHeight() / 2 + 20;

最后我们把图片画上去

 //指针图片
 needleMatrix.setTranslate(needlePoint.x, needlePoint.y);
 canvas.drawBitmap(needleBitmap, needleMatrix, null);
  • 现在我们来看看效果
    在这里插入图片描述
  • 看看,是不是和网易云的一样啦
  • 别急,我们还有最后一步,那就是指针在播放时和暂停时的位置是不一样的,我们注意到,指针在播放和暂停时,只是旋转了一下,我们来尝试实现一下
    我们先来修改一下指针默认的位置,默认是暂停的嘛
 private static final float NEEDLE_ROTATION_PLAY = 0.0f;//播放时指针的旋转角度
private static final float NEEDLE_ROTATION_PAUSE = -25.0f;//暂停时指针的旋转角度

我们定义一下指针旋转的中心点和定义一个属性动画

private Point needleCenterPoint = new Point();//指针旋转中心角度
private ValueAnimator needleAnimator;//播放时,指针旋转的属性动画

然后初始化属性动画

//初始化指针旋转动画
needleAnimator = ValueAnimator.ofFloat(NEEDLE_ROTATION_PAUSE, NEEDLE_ROTATION_PLAY);
needleAnimator.setDuration(500);
needleAnimator.addUpdateListener(animatorUpdateListener);
/**
* 属性动画变化监听器
*/
ValueAnimator.AnimatorUpdateListener animatorUpdateListener=new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            if(isPlaying){//判断是否正在播放
                needleRotation = (float) valueAnimator.getAnimatedValue();
            }else{
                needleRotation = - ((float) valueAnimator.getAnimatedValue() + 25);
            }
            invalidate();
        }
    };

最后在播放和暂停执行属性动画

needleAnimator.start();
  • 好了,最后我们再看效果
    在这里插入图片描述
    看,是不是和开始的效果一样啦~

代码和资源文件已经上传到Github,需要可以自取哦
Github:PlayView

第一次写博客,有些的不好的地方请大家见谅啊,欢迎大家留言交流~~~

PS:仿网易云播放页面的博客有很多,如有雷同,不慎巧合,哈哈T_T

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值