上一節咱們討論了一個音樂播放器應該具備的功能,當咱們實現了這些功能後,就該考慮如何擴展這些功能了。本節咱們要講的就是專輯封面的美化,看了市面上的播放器,最喜歡雲音樂的黑膠唱片專輯封面,下面咱們就來模仿一下。java
聲明變量git
// 圖片起始座標
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();
複製代碼
肯定圖片起始座標與旋轉中心座標github
@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
中。 繪製過程canvas
@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);
}
複製代碼
到這裏咱們已經能夠實現靜態的黑膠唱片專輯封面了,你們根據註釋確定能看懂。 接下來須要添加動畫,這裏使用勻速的屬性動畫。 旋轉動畫bash
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);
}
};
複製代碼
指針動畫app
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();
}
複製代碼
播放控制ide
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,讓咱們來看下效果post
基本上和雲音樂同樣的效果,並且能夠自適應屏幕大小,只是看不出來動畫效果。 你們能夠運行源碼或下載波尼音樂查看詳細效果。性能
遷移自個人簡書 2016.06.08優化