一款开源Android在线音乐播放器

    

本文是wangchenyan同窗的一个毕业设计做品,对于想研究音乐播放器的同窗,特别是歌词自定义滚动部分。以下:支持自动滚动,超长歌词自动换行,自定义属性。canvas


图片


简介

波尼音乐是一款开源Android在线音乐播放器。网络

  • 播放本地音乐与在线音乐ide

  • 在线音乐排行榜,如热歌榜、新歌榜等spa

  • 高仿云音乐的黑胶唱片专辑封面设计

  • 歌词显示,自动搜索歌词指针

  • 夜间模式orm

  • 定时关闭blog

更新说明

  • 新增通知栏播放控制图片

  • 修复魅族手机扫描不到音乐的问题get

  • 修复已知bug

  • 修复在线音乐没法加载的问题

  • 修复弱网时播放网络歌曲致使ANR的问题

  • 修复每日启动图片没法更新的问题

  • 下载在线歌曲能够显示专辑封面了

  • 修复已知bug

  • 支持 Android 6.0 运行时权限

  • 修复已知bug

  • First Release

公开API

  • 在线音乐:百度音乐

  • 天气数据:高德地图

开源技术

  • okhttp-utils

  • Glide

关键代码

黑胶唱片专辑封面绘制流程

@Overrideprotected 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);}

歌词绘制流程

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    // 中心Y坐标    float centerY = getHeight() / 2 + mTextSize / 2 + mAnimOffset;    // 无歌词文件    if (!hasLrc()) {        float centerX = (getWidth() - mCurrentPaint.measureText(label)) / 2;        canvas.drawText(label, centerX, centerY, mCurrentPaint);        return;    }    // 画当前行    String currStr = mLrcTexts.get(mCurrentLine);    float currX = (getWidth() - mCurrentPaint.measureText(currStr)) / 2;    canvas.drawText(currStr, currX, centerY, mCurrentPaint);    // 画当前行上面的    for (int i = mCurrentLine - 1; i >= 0; i--) {        String upStr = mLrcTexts.get(i);        float upX = (getWidth() - mNormalPaint.measureText(upStr)) / 2;        float upY = centerY - (mTextSize + mDividerHeight) * (mCurrentLine - i);        // 超出屏幕中止绘制        if (upY - mTextSize < 0) {            break;        }        canvas.drawText(upStr, upX, upY, mNormalPaint);    }    // 画当前行下面的    for (int i = mCurrentLine + 1; i < mLrcTimes.size(); i++) {        String downStr = mLrcTexts.get(i);        float downX = (getWidth() - mNormalPaint.measureText(downStr)) / 2;        float downY = centerY + (mTextSize + mDividerHeight) * (i - mCurrentLine);        // 超出屏幕中止绘制        if (downY > getHeight()) {            break;        }        canvas.drawText(downStr, downX, downY, mNormalPaint);    }}

截图

图片图片图片图片图片

图片

相关文章
相关标签/搜索