android播放器实现歌词显示功能

网上android播放器虽然挺多,感觉提供的歌词显示功能比较死板,要么搜索给的条件死死的,要么放置sdcard内部的歌词格式需要统一,应该提供类似文件夹浏览的功能。^_^,不过在这之前先搞定歌词的现实界面:

播放器的歌词界面实现以下几个功能

  • 根据歌曲的播放进度自下而上滚动;
  • 提供上下拖动调整歌曲进度的功能;
  • 突出显示当前进度的歌词段,并保证该歌词段处于布局中心

不多说了直接贴代码,首先开启一个线程每隔一段时间往view中送入一串字符

Java代码

import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; 

public class TextAlign extends GraphicsActivity implements OnClickListener { 

  private SampleView mView; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Animation in = AnimationUtils.loadAnimation(this, R.anim.push_up_in); 

    // mView.setAnimation(in);
    setContentView(R.layout.main);
    mView =(SampleView) findViewById(R.id.text01); 

    Button bt = (Button) findViewById(R.id.Button01);
    bt.setOnClickListener(this); 

    new Thread(new UIUpdateThread()).start(); 

  } 

  class UIUpdateThread implements Runnable {
    long time = 40000; 

    long sleeptime = 100;
    public void run() {
      try {
        while (time < 200000) {
          Thread.sleep(sleeptime);
          mView.updateIndex(time);//.index = mLyric.getNowSentenceIndex(time);
//         Log.v("UIThread", mView.index + ":" + time);
          time += sleeptime;
          mHandler.post(mUpdateResults);
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
  Handler mHandler = new Handler();
  Runnable mUpdateResults = new Runnable() {
    public void run() {
      mView.invalidate(); // 更新视图
    }
  }; 

  @Override
  public void onClick(View v) {
    mView.mTouchHistoryY -=30;
    mHandler.post(mUpdateResults);
  }
} 

这里将时间送到SampleView中,该类对此时间进行加工得到一系列list(该list是动态生成的),从而根据时间的推移递增的得到一系列的字串。这个过程模拟了歌词的显示过程

接下来的SampleView继承了TextView并重载了onDraw方法.注意,这里只给了个sample,里面歌词怎么生成的见YOYOPlayer。这里就不给代码了

Java代码

import java.io.File;
import java.util.List; 

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.TextView;
import android.widget.Toast; 

import com.android.lyric.Lyric;
import com.android.lyric.PlayListItem;
import com.android.lyric.Sentence; 

public class SampleView extends TextView {
    private Paint mPaint;
    private float mX;
    private static Lyric mLyric; 

    private Path mPath;
    private Paint mPathPaint;
    public String test = "test";
    public int index = 0;
    private List<Sentence> list; 

    private float mTouchStartY;
    private float mTouchCurrY;
    public float mTouchHistoryY; 

    private int mY;
    private long currentTime;
    private long currentDunringTime;
    private long sentenctTime;
    private float middleY;
    private String middleContent="Empty";
    private static final int DY = 30; 

    private static void makePath(Path p) {
      p.moveTo(10, 0);
      p.cubicTo(100, -50, 200, 50, 300, 0);
    } 

    public SampleView(Context context) {
      super(context);
      init();
    }
    public SampleView(Context context,AttributeSet attr) {
      super(context,attr);
      init();
    }
    public SampleView(Context context,AttributeSet attr,int i) {
      super(context,attr,i);
      init();
    } 

    private void init() {
      setFocusable(true);
      PlayListItem pli = new PlayListItem("", "", 1000L, true);
      mLyric = new Lyric(new File("/sdcard/M0005044007.lrc"), pli); 

      list = mLyric.list;
      mPaint = new Paint();
      mPaint.setAntiAlias(true);
      mPaint.setTextSize(20);
      mPaint.setTypeface(Typeface.SERIF); 

      mPath = new Path();
      makePath(mPath); 

      mPathPaint = new Paint();
      mPathPaint.setAntiAlias(true);
      mPathPaint.setColor(0x800000FF);
      mPathPaint.setStyle(Paint.Style.STROKE);
    } 

    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas); 

      canvas.drawColor(Color.WHITE); 

      Paint p = mPaint;
      float x = mX;
      float plus =currentDunringTime==0?index*30: index*30 +(((float)currentTime - (float)sentenctTime)/(float)currentDunringTime)*(float)30;
      float y = mY- plus+mTouchCurrY - mTouchStartY+mTouchHistoryY; 

      canvas.translate(0,y); 

      for (int i = 0; i < index; i++) {
        String text = list.get(i).getContent();
        if((y+i*30)<=middleY&&(y+i*30+30)>=middleY)
          middleContent = text;
        p.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(text, x, 0, p);
        // mY- mY/lines*(index - i)
        canvas.translate(0, DY);
      }
    } 

    @Override
    protected void onSizeChanged(int w, int h, int ow, int oh) {
      super.onSizeChanged(w, h, ow, oh);
      mX = w * 0.5f; // remember the center of the screen
      mY = h;
      middleY = h*0.5f;
    } 

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      float y = event.getY(); 

      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mTouchHistoryY += mTouchCurrY - mTouchStartY;
        mTouchStartY =mTouchCurrY= y;
        invalidate();
        break;
      case MotionEvent.ACTION_MOVE:
        mTouchCurrY = y;
        invalidate();
        break;
      case MotionEvent.ACTION_UP:
        Log.v("Lyric content", middleContent.length()+"");
        CharSequence chars = new CharSequence(){ 

          @Override
          public char charAt(int index) {
            // TODO Auto-generated method stub
            return middleContent.charAt(index);
          } 

          @Override
          public int length() {
            // TODO Auto-generated method stub
            return middleContent.length();
          } 

          @Override
          public CharSequence subSequence(int start, int end) {
            // TODO Auto-generated method stub
            return middleContent.subSequence(start, end);
          }
          @Override
          public String toString(){
            return middleContent;
          }
        };
        Toast toast = Toast.makeText(SampleView.this.getContext(),chars, 1000);
        toast.show();
        invalidate();
        break;
      }
      return true;
    } 

    public void updateIndex(long time) {
      this.currentTime = time;
      index = mLyric.getNowSentenceIndex(time);
      Sentence sen = list.get(index);
      currentDunringTime = sen.getDuring();
      sentenctTime = sen.getFromTime();
    }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现音乐播放器歌词显示效果

    这两天有个任务,说是要写一个QQ音乐播放器歌词的那种效果,毕竟刚学自定义View,没有什么思路,然后就Google.写了一个歌词效果,效果图在后面,下面是我整理的代码. 首先实现这种效果有两种方式 1.自定义View里重载onDraw方法,自己绘制歌词 2.用ScrollView实现 第一种方式比较精确,但要支持滑动之后跳转播放的话难度很大,所以我选择第二种,自定义ScrollView 我也不多说,直接上代码,代码中有注释 一.自定义LycicView extends ScrollView 里面

  • android播放器实现歌词显示功能

    网上android播放器虽然挺多,感觉提供的歌词显示功能比较死板,要么搜索给的条件死死的,要么放置sdcard内部的歌词格式需要统一,应该提供类似文件夹浏览的功能.^_^,不过在这之前先搞定歌词的现实界面: 播放器的歌词界面实现以下几个功能 根据歌曲的播放进度自下而上滚动: 提供上下拖动调整歌曲进度的功能: 突出显示当前进度的歌词段,并保证该歌词段处于布局中心 不多说了直接贴代码,首先开启一个线程每隔一段时间往view中送入一串字符 Java代码 import android.os.Bundle

  • Java swing实现音乐播放器桌面歌词字体变色效果

    最近看到某音乐播放器的桌面歌词如下图 其中字母"U"有两种颜色,突发奇想想模仿一下实现文字变色. 思路:使用两种颜色分别把字符串绘制到两个BufferedImage中,然后根据两种颜色所占空间的比值分别擦除两个BufferedImage中的对应内容,最后再把两个BufferedImage合为一个. 效果图 可以通过以下代码更改两种颜色的比值 StringTwoColor stc = new StringTwoColor(jl1, Color.RED, Color.gray, 0.8);

  • Android 使用Vitamio打造自己的万能播放器(4)——本地播放(快捷搜索、数据存储)

    前言 关键字:Vitamio.VPlayer.Android播放器.Android影音.Android开源播放器 本章节把Android万能播放器本地播放的主要功能(缓存播放列表和A-Z快速查询功能)完成,和播放组件关系不大,但用到一些实用的技术,欢迎交流! 系列 1.Android 使用Vitamio打造自己的万能播放器(1)--准备 2.Android 使用Vitamio打造自己的万能播放器(2)-- 手势控制亮度.音量.缩放 3.Android 使用Vitamio打造自己的万能播放器(3)

  • Android 使用Vitamio打造自己的万能播放器(3)——本地播放(主界面、播放列表)

    前言 打造一款完整可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment.ViewPager来搭建播放器的主界面,并实现本地播放基本功能.系列文章提供截图.代码说明.源码下载,欢迎交流! 系列 1.Android 使用Vitamio打造自己的万能播放器(1)--准备 2.Android 使用Vitamio打造自己的万能播放器(2)-- 手势控制亮度.音量.缩放  正文 一.目标 1.1 使用Fragment.ViewPager搭建主界面 主功

  • Android 使用Vitamio打造自己的万能播放器(7)——在线播放(下载视频)

    前言 本章将实现非常实用的功能--下载在线视频.涉及到多线程.线程更新UI等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术细节实现! 系列 1.Android 使用Vitamio打造自己的万能播放器(1)--准备 2.Android 使用Vitamio打造自己的万能播放器(2)-- 手势控制亮度.音量.缩放 3.Android 使用Vitamio打造自己的万能播放器(3)--本地播放(主界面.视频列表) 4.Andro

  • Android编程之播放器MediaPlayer实现均衡器效果示例

    本文实例讲述了Android播放器MediaPlayer实现均衡器效果.分享给大家供大家参考,具体如下: 这几天在系统学习Android官方API Demos,看到实现均衡器效果,就把官方API中代码copy下来,根据网上前辈的指引略有修改,添加了注释. public class AudioFxDemo extends Activity { private static final String TAG = "AudioFxDemo"; private static final flo

  • vue一个页面实现音乐播放器的示例

    本文介绍了vue一个页面实现音乐播放器的示例,分享给大家,具体如下: 效果如下: 项目地址:https://github.com/ermu592275254/MiniMusicPlayer 演示地址: https://ermu592275254.github.io/MiniMusicPlayer/(歌曲链接已失效) 开发前构思 界面 做音乐播放器,界面一定要炫酷.太low了听歌没感觉.本身是为了在上班的时候用,于是做成了一个类似网易云音乐的界面,大小合适.不用兼容手机端. 用css做图标 本怀着

  • 基于JavaScript实现一个月饼音乐播放器

    目录 前言 页面布局 页面背景 左侧列表 中间播放器 右侧歌词部分 总结 前言 事情的经过是这样的,媳妇中秋发了一盒月饼,里面还有一个小蓝牙音响,她说如果这个音响是个月饼造型之类的是不是更能体现出中秋的气氛.于是我就想到了可以用代码给她实现一个啊,拿出了我仅有的一点点前端看家本领(我是搞后端的),浪费我三天假期,效果图如下,本来设想的挺好,可是由于本人能力有限,没有达到自己预想的目标,仅供娱乐! 页面布局 页面采用最简单的div+css进行布局,首先将页面分为三部分,分别为左边音乐列表,中间播放

  • Android 开源在线音乐播放器

    封面图:  简介 波尼音乐是一款开源Android在线音乐播放器. 播放本地音乐与在线音乐 在线音乐排行榜,如热歌榜.新歌榜等 高仿云音乐的黑胶唱片专辑封面 歌词显示,自动搜索歌词 夜间模式 定时关闭 更新说明 v 1.0 First Release TODO 在线音乐可以免下载加入我的音乐列表 在线音乐自动缓存 编辑音乐信息 项目公开API 在线音乐:百度音乐 天气数据:高德地图 开源技术 okhttp-utils Android-Universal-Image-Loader 关键代码 黑胶唱

随机推荐