LrcView逐行歌词
来源:互联网 发布:这个男人来自地球知乎 编辑:程序博客网 时间:2024/04/29 21:34
今天来谈谈歌词控件的实现。大体思路
先解析歌词,歌词配合控件的宽高计算坐标(歌词必须显示在行的中间),然后进行绘制onDraw,最后就是事件处理(歌词 拖动)和歌词随着时间自动移动,这个相对比较麻烦点。
小二 先上个图看看效果
来一段歌词源数据
[02:59.03][01:31.44]双眼也不需要魅力的长发也不需要魅力的长发[03:07.54][01:33.99]我真不知道我们的命运会这样知道我们的命运会这样[03:16.36][01:38.59]我只能牺牲自己的感情离你远去只能牺牲自己的感情离你远去[03:51.19][01:46.80]我只好让你伤心的流泪[03:52.94][01:57.69]远离你的世界[03:55.07][02:02.47]我其实不需要你美丽的双眼[03:57.81][02:06.22]也不需要魅力的长发
按照上面格式对数据进行解析,这里比较简单,开始绘制,网上很多哥们说绘制的时候先绘制高亮区域,然后绘制高亮之前或者后面的歌词,我觉得没必要,只要坐标计算好了,拿起键盘一阵狂干,完事
if (lrcs == null || lrcs.size() == 0) { //没有歌词 canvas.drawText(noLrc, nolrcX, center, mNormalpaint); return; } for (int i = 0, size = lrcs.size(); i < size; i++) { LrcBean lrcBean = lrcs.get(i); String lrc = lrcBean.getLrc(); if (!TextUtils.isEmpty(lrc)) { if (playTime >= lrcBean.getBeginTime() && playTime < lrcBean.getEndTime()) { canvas.drawText(lrc, lrcBean.getX(), lrcBean.getY(), mHighLightpaint); } else { canvas.drawText(lrc, lrcBean.getX(), lrcBean.getY(), mNormalpaint); } } }
public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: y = event.getY(); isMoving = (isStop ? false : true); isClick = true; break; case MotionEvent.ACTION_MOVE: float durY = event.getY() - y; if (Math.abs(durY) > scaledTouchSlop / 2) { isClick = false; if (mlrcs.size() > 0 && !isStop) { if (getScrollY() < 0) { durY = durY / 3; } else if (getScrollY() > mlrcs.size() * wordHight) { durY = durY / 3; } scrollBy(getScrollX(), -(int) durY); y = event.getY(); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: int old = getScrollY(); if (old < 0) { smootscroll(mLrcDrawTool.getIndexline() * (wordHight) - old, ANIMATION_TIME, old); } else if (getScrollY() > mlrcs.size() * wordHight) { smootscroll(mLrcDrawTool.getIndexline() * (wordHight) - old, ANIMATION_TIME, old); } if (isClick) { isClick = true; if (mOnclicklisener != null) { mOnclicklisener.onClick(); } } invalidate(); isMoving = false; break; } return true; }
细心的你肯定会发现这里做了一个小小的处理,当歌词第一行歌词或者最后一个歌词滑动到中间位置的时候,把滑动偏移量消耗了一部分,效果看起来会好点。
下面就是重头戏,随着时间自动滚动。
int indexline = mLrcDrawTool.getIndexline(); if (preLrc != indexline) { int old = getScrollY(); int offset = indexline * wordHight - old; smootscroll(offset, durtime, old); preLrc = indexline; invalidate(); }
getScrollY 这个方法很重要,getScrollY就是当前view的左上角相对于母视图的左上角的Y轴偏移量。 当歌词第一移动上去,getScrollY的值也是变化一行歌词的高度,通过这种方式就可以计算出每次歌词的偏移量,然后给mScroller.startScroll(getScrollX(), old, getScrollX(), offset, durtime);传值,实现自动滚动。
好了逐行歌词已经完成,下面是demo地址
LrcView
如果想了解更多可以关注公众号:
阅读全文
1 0
- LrcView逐行歌词
- 歌词
- 歌词
- 歌词
- 歌词
- 歌词
- 歌词
- 歌词
- 歌词
- 歌词
- 逐行计算、逐行递延、逐行更新。
- 逐行update
- java逐行读逐行写
- java逐行读逐行写
- 逐行读取readline 和 逐行写入
- 留心(歌词)
- 经典歌曲歌词
- 三暝三日歌词
- servlet之session
- JavaWeb第四记《session》相关知识
- iOS 序列化与反序列化(runtime) 02
- UESTC 1705 咸鱼钟大爷 随机化+哈希
- 可直接用于React Native开发各种加密标准的JavaScript库(MD5,AES,DES,SHA...)
- LrcView逐行歌词
- Android中实现震动的方法
- VS2015编译FFmpeg3.3.1源码
- 工作日记2017.07.18
- 信源作业四:LZO算法的压缩与解压技术
- 阿里巴巴2016 实习生招聘练习题(二)
- MathJax基础(6):间距问题
- zabbix3.2短信告警脚本
- SELinux: Could not downgrade policy file