今天遇到一个很奇怪的问题,关于在view里面更新LRC歌词的,view里面有一个成员变量,lrcindex ,在draw里面会用到它来更新歌词,歌词里面有一行是红色的,表示当前正在播放的歌词。然后我拖动seekbar同时更新歌词显示,我在onProgressChanged里面更新,其他颜色的歌词能正常显示,就是那个红色的歌词还是暂停之前那句,没有更新,怎么拖都没用。我打印出了draw里面那个lrcindex,值没变 还是暂停之前的值。但是实际上我在另外一个函数根据当前播放时间获取当前歌词的时候已经修改了lrcindex,这是怎么回事?
我做的是一个音乐播放器,动态更新歌词和进度条的。
给你们看一下我的代码(只摘取部分关键的)
<span style="font-size:18px;">seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mp.seekTo(seekBar.getProgress());//mp是播放音乐的服务,这个方法用来设置mediaplayer的进度
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
mp.stopUpdate();//停止自动更新进度条时间和歌词
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// 这个是一个回调函数,只要seekbar的值改变,系统就会调用这个方法。
<span style="white-space:pre"> </span>System.out.println(220
- lyricView.SelectIndex(seekBar.getProgress())
* (lyricView.getSIZEWORD()
+ lyricView.getINTERVAL() - 1));
System.out.println(lyricView.SelectIndex(progress) + "--- "
+ lyricView.getSIZEWORD() + "--"
+ (lyricView.getINTERVAL() - 1));
lyricView.setOffsetY(220
- lyricView.SelectIndex(progress)
* (lyricView.getSIZEWORD()
+ lyricView.getINTERVAL() - 1));
lyricView.SelectIndex(mp.getplayer().getCurrentPosition());
lyricView.setLrcIndex(lyricView.SelectIndex(progress));
lyricView.invalidate();//更新视图
}
}
});
}
</span>
我每次更新歌词的进度后,都会调用invalidate来更新视图,而且控制台也输出了draw里面调试信息,lrcindex和我在seekbar值改变监听器里面获取到的就是不一样。再来看一下,selectIndex方法
<span style="font-size:18px;">public int SelectIndex(int time) {
if (!blLrc) {
return 0;
}
int index = 0;
for (int i = 0; i < lrc_map.size(); i++) {
LyricObject temp = lrc_map.get(i);
if (temp.begintime <= time) {
++index;
}
}
lrcIndex = index - 1;
if (lrcIndex < 0) {
lrcIndex = 0;
}
System.out.println("lrcindex-->>" + lrcIndex);
return lrcIndex;
}</span>
我明明更改了,lrcindex的值,但是在draw里面就是获取不到它更改后的值。在我松开手之前,lrcindex的值一直是暂停之前的值(我是暂停后拖动seekbar)。松开手后在点播放或者再拖动一下seekbar,它会显示之前拖动更改后开始打印进度信息。
我在lrcview(显示歌词的那个视图)里面查找过lrcindex,除了我自己添加的set方法外就只有selectindex方法可以修改lrcindex的值。
后来 我在lrcview.draw里面不直接用lrcindex这个成员,我在selectindex里面调用setlrcindex来设置lrcindex,再在draw里面使用getlrcindex结果就对了,拖动seekbar的时候可以正常显示所有歌词,包括那个红色的当前正在播放的一句。LyricObject temp = lrc_map.get(getLrcIndex());原来的get()里面的参数是lrcindex。
我学android有一年多了,但是从来没遇到这个问题,我也不是那种很不通窍的,这次遇到应该不是简单地问题。感觉好奇怪。。。。
今年刚学了操作系统,当时在Linux环境下创建一个新的进程,新的进程再调用代码里面的变量x的时候,x实际上是父进程里面的x的拷贝,修改子进程里面的x不会更改父进程里面的x的值,难道这里也是这个问题?draw跟我的应用不在一个进程吗?
下面上一下我的截图,貌似真是两个进程在执行draw。。。
大家看得到,我鼠标拖动了,当前的红色歌词已经不是我要显示的歌词了,正常显示的应该是在屏幕中间的下方一点。
上图是我打印的信息,红色箭头指向的都是lrcindex的输出信息,奇怪的是 我在selectindex里面输出的"-->>"居然在前后输出了两个不同的值,49 28,49是我拖动的时候动态显示的,表示当前歌词条数在LRC文件里面的索引,这个是正确的,而28是我touchseekbar拖动之前的数值。看样子真是有两个进程打印lrcindex的值。
即使是两个进程,那为什么只有我松开了手,那个lrcindex才会更新呢?虽然学android时间也不短了,但是对android还是有很多不懂得,望大神能解释一下