一、在Android中,不能在主线程中更新布局,这样可能抛出Response Exception。
需要开启一个线程来不断更新动态的视图,如此才不会影响到主线程的运行。
同样的,也不能在主线程中直接下载网络文件这些比较费时的操作,如果一直没有响应,
主线程可能直接崩溃,退出程序。解决的办法也是开启一个线程。
二、要动态显示歌词,必须自定义一个View类。(说明一下,此类大部分代码引用自网络,被我修改来满足我们的需求)
比如我的代码定义为LrcSurfaceView ,它继承自SurfaceView ,并实现Runnable接口的run方法,已经实现
SurfaceHolder.Callback;
具体代码如下:
//构造函数
public LrcSurfaceView(Context context, AttributeSet attrs)
{
super(context, attrs);
mSurfaceHolder = this.getHolder(); //获取Holder
mSurfaceHolder.addCallback(this); //必须调用callback
this.setFocusable(false); //获取焦点
mbLoop = true;
}
boolean mbLoop = false;
SurfaceHolder mSurfaceHolder = null; //SurfaceHolder 对象
//构造函数
public LrcSurfaceView(Context context)
{
super(context);
mSurfaceHolder = this.getHolder(); //获取Holder
mSurfaceHolder.addCallback(this);
this.setFocusable(false);
mbLoop = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
new Thread(this).start(); //启动一个线程,更新控件
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
mbLoop = false;
}
@Override
public void run() //实现Runnable接口
{
while (mbLoop)
{
try
{
Thread.sleep(100);
} catch (Exception e) {}
synchronized( mSurfaceHolder )
{
Draw(); //绘图我们的图形(在这里可以发挥想象空间)
}
}
}
public void Draw() //歌詞显示
{
Canvas canvas = mSurfaceHolder.lockCanvas(); //创建画布
if (mSurfaceHolder==null || canvas == null)
{
return;
}
mPaint.setColor(Color.argb(200,80, 80, 80)); //mPaint设置画布颜色
canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint); //画一个长方形用于显示歌词
mPaint.setColor(Color.argb(255,50,150,150));
mPath.moveTo(2, getHeight());
mPath.lineTo(getWidth(), getHeight());
if(isPlay)
{
final float offsetCopy = hOffset;
if(mContentLine>SongInfor.getContent().length)
{
mContentLine=0;
}
if((xAdd+offsetCopy)<=getWidth())
{
canvas.drawTextOnPath(SongInfor.getContent()[mContentLine].trim(),mPath, xAdd+offsetCopy,-5, mPaint);
xAdd=xAdd+6;
}
else
{
xAdd=-SongInfor.getContent()[mContentLine].trim().length();
mContentLine++;
canvas.drawTextOnPath(SongInfor.getContent()[mContentLine].trim(),mPath, xAdd+offsetCopy,-5, mPaint);
}
}
else
{
canvas.drawTextOnPath(SongInfor.getContent()[mContentLine].trim(),mPath, 6,-5, mPaint);
}
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
public void setPlay(boolean flag)
{
this.isPlay=flag;
}
主要思路是,在view类创建的时候,开启一个线程,然后我们覆写run方法,在里面不断更新歌词的显示。
显示歌词的地方时一个canvas,然后我们在画布上不断用canvas.drawTextOnPath方法来画。
三、然后我们在xml文件中把此类引用。
四、在MainActivity中像往常的View调用就OK啦。
类似代码如下:
五、最后就能出下面的效果。