android高仿音乐播放器,Android开源音乐播放器之高仿云音乐黑胶唱片

系列文章

前言

上一节我们讨论了一个音乐播放器应该具有的功能,当我们实现了这些功能后,就该考虑如何扩展这些功能了。本节我们要讲的就是专辑封面的美化,看了市面上的播放器,最喜欢云音乐的黑胶唱片专辑封面,下面我们就来模仿一下。

思路分析

938e2e90126914e1416280c6ffcecf81.png

让我们来分析下这个View,这里有5个地方需要绘制

1.最上面的一条虚线,这个简单。

2.黑胶外侧的半透明边框,这个不需要旋转也比较简单。

3.黑胶

4.专辑封面

为了能使黑胶和封面能完美融合,因此我们需要固定它们的尺寸,这里设置黑胶直径为屏幕的3/4,封面直径为屏幕的一半,即封面直径为黑胶直径的2/3。

5.指针,这个在暂停时会有一个旋转动画,因此注意选择好旋转圆心和半径坐标,为了使指针能够放在黑胶正中,我们需要固定指针的高度为黑胶直径的一半。

4e93f0422287062bdebe10e420c97408.png

代码实现

声明变量

// 图片起始坐标

private Point mDiscPoint = new Point();

private Point mCoverPoint = new Point();

private Point mNeedlePoint = new Point();

// 旋转中心坐标

private Point mDiscCenterPoint = new Point();

private Point mCoverCenterPoint = new Point();

private Point mNeedleCenterPoint = new Point();

复制代码

确定图片起始坐标与旋转中心坐标

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

super.onLayout(changed, left, top, right, bottom);

initSize();

}

/**

* 确定图片起始坐标与旋转中心坐标

*/

private void initSize() {

int discOffsetY = mNeedleBitmap.getHeight() / 2;

mDiscPoint.x = (getWidth() - mDiscBitmap.getWidth()) / 2;

mDiscPoint.y = discOffsetY;

mCoverPoint.x = (getWidth() - mCoverBitmap.getWidth()) / 2;

mCoverPoint.y = discOffsetY + (mDiscBitmap.getHeight() - mCoverBitmap.getHeight()) / 2;

mNeedlePoint.x = getWidth() / 2 - mNeedleBitmap.getWidth() / 6;

mNeedlePoint.y = -mNeedleBitmap.getWidth() / 6;

mDiscCenterPoint.x = getWidth() / 2;

mDiscCenterPoint.y = mDiscBitmap.getHeight() / 2 + discOffsetY;

mCoverCenterPoint.x = mDiscCenterPoint.x;

mCoverCenterPoint.y = mDiscCenterPoint.y;

mNeedleCenterPoint.x = mDiscCenterPoint.x;

mNeedleCenterPoint.y = 0;

}

复制代码

每次绘制都会进行重复计算,为了优化性能,我们把计算的过程放在onLayout中。

绘制过程

@Override

protected void onDraw(Canvas canvas) {

// 1.绘制顶部虚线

mTopLine.setBounds(0, 0, getWidth(), mTopLineHeight);

mTopLine.draw(canvas);

// 2.绘制黑胶唱片外侧半透明边框

mCoverBorder.setBounds(mDiscPoint.x - mCoverBorderWidth, mDiscPoint.y - mCoverBorderWidth,

mDiscPoint.x + mDiscBitmap.getWidth() + mCoverBorderWidth, mDiscPoint.y +

mDiscBitmap.getHeight() + mCoverBorderWidth);

mCoverBorder.draw(canvas);

// 3.绘制黑胶

// 设置旋转中心和旋转角度,setRotate和preTranslate顺序很重要

mDiscMatrix.setRotate(mDiscRotation, mDiscCenterPoint.x, mDiscCenterPoint.y);

// 设置图片起始坐标

mDiscMatrix.preTranslate(mDiscPoint.x, mDiscPoint.y);

canvas.drawBitmap(mDiscBitmap, mDiscMatrix, null);

// 4.绘制封面

mCoverMatrix.setRotate(mDiscRotation, mCoverCenterPoint.x, mCoverCenterPoint.y);

mCoverMatrix.preTranslate(mCoverPoint.x, mCoverPoint.y);

canvas.drawBitmap(mCoverBitmap, mCoverMatrix, null);

// 5.绘制指针

mNeedleMatrix.setRotate(mNeedleRotation, mNeedleCenterPoint.x, mNeedleCenterPoint.y);

mNeedleMatrix.preTranslate(mNeedlePoint.x, mNeedlePoint.y);

canvas.drawBitmap(mNeedleBitmap, mNeedleMatrix, null);

}

复制代码

到这里我们已经可以实现静态的黑胶唱片专辑封面了,大家根据注释肯定能看懂。

接下来需要添加动画,这里使用匀速的属性动画。

旋转动画

private Runnable mRotationRunnable = new Runnable() {

@Override

public void run() {

if (isPlaying) {

mDiscRotation += DISC_ROTATION_INCREASE;

if (mDiscRotation >= 360) {

mDiscRotation = 0;

}

invalidate();

}

mHandler.postDelayed(this, TIME_UPDATE);

}

};

复制代码

指针动画

mPlayAnimator = ValueAnimator.ofFloat(NEEDLE_ROTATION_PAUSE, NEEDLE_ROTATION_PLAY);

mPlayAnimator.setDuration(300);

mPlayAnimator.addUpdateListener(this);

mPauseAnimator = ValueAnimator.ofFloat(NEEDLE_ROTATION_PLAY, NEEDLE_ROTATION_PAUSE);

mPauseAnimator.setDuration(300);

mPauseAnimator.addUpdateListener(this);

@Override

public void onAnimationUpdate(ValueAnimator animation) {

mNeedleRotation = (float) animation.getAnimatedValue();

invalidate();

}

复制代码

播放控制

public void start() {

if (isPlaying) {

return;

}

isPlaying = true;

mHandler.post(mRotationRunnable);

mPlayAnimator.start();

}

public void pause() {

if (!isPlaying) {

return;

}

isPlaying = false;

mHandler.removeCallbacks(mRotationRunnable);

mPauseAnimator.start();

}

复制代码

播放时启动旋转动画,播放指针动画,暂停时暂停动画,播放指针动画。

OK,让我们来看下效果

1a138667cd9591b7a6293b4ef58a2c9d.png

基本上和云音乐一样的效果,而且可以自适应屏幕大小,只是看不出来动画效果。

大家可以运行源码或下载波尼音乐查看详细效果。

迁移自我的简书

2016.06.08

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值