我有一个自定义的Android视图,可以在屏幕上绘制波形。 一个变量,cursorTask是一个TimerTask,它在startCursor结束执行和stopCursor被调用之间以某种方式变为null。我不知道这是如何发生的,因为它是私有的,所有的WaveView的startCursor函数都被调用。
public class WaveView extends View {
private Audio audio;
Paint wavePaint;
Paint progressPaint;
Paint barPaint;
private int progress;
private int maxProgress = 100;
private Timer timer;
private TimerTask cursorTask;
public WaveView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
timer = new Timer();
wavePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
wavePaint.setColor(Color.BLUE);
wavePaint.setStyle(Paint.Style.FILL);
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
progressPaint.setColor(Color.RED);
progressPaint.setStrokeWidth(2.0f);
barPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
barPaint.setColor(Color.CYAN);
barPaint.setAlpha(100);
}
public void setAudio(Audio audio){
this.audio = audio;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(audio != null && audio.waveValues != null && !audio.waveValues.isEmpty()){
int w = canvas.getWidth();
int h = canvas.getHeight();
canvas.drawRect(new Rect(0, 0, w*audio.bars/Rhythm.maxBars, h), barPaint);
Path path = new Path();
path.moveTo(0,h);
for(int i = 0; i < 100; i++){
int x = i * w/100;
if(audio.waveValues.size() <= i){
path.lineTo(x, h);
break;
}
int y = Math.round(h-audio.waveValues.get(i)*h);
path.lineTo(x, y);
}
path.lineTo(w,h);
canvas.drawPath(path, wavePaint);
if(0 < progress){
float x = progress*w*audio.bars/maxProgress/Rhythm.maxBars;
canvas.drawLine(x, h, x, 0, progressPaint);
}
}
}
public void startCursor(int msLoopDuration){
progress = 0;
cursorTask = new TimerTask() {
@Override
public void run() {
progress = (progress+1) % maxProgress;
postInvalidate();
}
};
timer.scheduleAtFixedRate(cursorTask, 0, msLoopDuration/maxProgress);
}
public void stopCursor(){
cursorTask.cancel();
}
}
我通过在WaveView所在的适配器中的getView()中的convertView中找到WaveView来调用它。
WaveView wave = (WaveView)convertView.findViewById(R.id.waveform);
wave.startCursor(Rhythm.msBarPeriod()*audio.bars);
非常感谢任何帮助。