私はプログラムを持っています。私は音楽ノートを演奏するはずのアンドロイドスタジオで書き込みをしています。座標、曲名、時間のアーリーリストに基づいてサイズを拡大していますノートを演奏する。しかし、私が抱えている問題は、すべての音符が正しく再生されていることです。しかし最後の円だけが描画されますとすべての音符を再生するループを終了した後。私はこの質問を以前に調べましたが、setWillNotDraw(false);
を呼び出すことについていくつかの回答がありましたが、私はそれを私のコンストラクタで呼び出しましたが、私はまだ同じ問題を抱えています。私は複数の異なる場所でinvalidate();
を呼び出すことを試みましたが、何も動作していないようです。どんな助けでも大歓迎です!OnDraw()はループ後に一度だけ呼び出されます
マイコード:
コンストラクタ
public PlayView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
saver = PersistentSaver.getInstance(context);
this.context=context;
setWillNotDraw(false);
}
で
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
this.canvas=canvas;
if(mCurrentRect !=null&& colorPaint!=null) {
canvas.drawOval(mCurrentRect, colorPaint);
}
}
私がチェックしたnotes-を再生するループを描き、すべての円座標とノートが正しい配列に含まれています:
public void playSong(){
String song = saver.getCurrSongName();
ArrayList<Long> Times = saver.getTimesForNotes(song);
ArrayList<Float> xCoordinates = saver.getPressXCoordinates(song);
ArrayList<Float> yCoordinates = saver.getPressYCoordinates(song);
ArrayList<String> notes = saver.getNotesForSong(song);
for(int i=0;i<Times.size();i++) {
//pause until correct time. TODO: ADJUST ERROR BOUND
while (true) {
currTime = System.currentTimeMillis() - startTime;
if (currTime <= Times.get(i) + epsilon && currTime >= Times.get(i) - epsilon) break;
}
//play note with that x and y coordinate and draw circle
playNote(xCoordinates.get(i), yCoordinates.get(i), notes.get(i));
}
}
コードは、ノートやサウンドを再生します
private void playNote(float pressx, float pressy, String note){
colorPaint=new Paint();
colorPaint.setStyle(Paint.Style.STROKE);
colorPaint.setStrokeWidth(10);
colorPaint.setColor(generateColor(pressx,pressy));
float translateX = 50.0f;
float translateY = 50.0f;
Random rand = new Random(10000);
int xr = rand.nextInt();
int yr = rand.nextInt();
int startColor = generateColor(pressx,pressy);
int midColor = generateColor(pressx+rand.nextInt(),pressy+rand.nextInt());
int endColor = generateColor(pressx+xr,pressy+yr);
mCurrentRect = new AnimatableRectF(pressx-50,pressy-50,pressx+50,pressy+50);
debugx=pressx;
playAnimation(startColor,midColor,endColor, translateX, translateY);
playSound(note);
}
アニメーションを再生するにはを想定しているが、ループが終了した後にのみonDraw();
を呼び出しているコード
private void playAnimation(int startColor, int midColor, int endColor, float translateX, float translateY){
ObjectAnimator animateLeft = ObjectAnimator.ofFloat(mCurrentRect, "left", mCurrentRect.left, mCurrentRect.left-translateX);
ObjectAnimator animateRight = ObjectAnimator.ofFloat(mCurrentRect, "right", mCurrentRect.right, mCurrentRect.right+translateX);
ObjectAnimator animateTop = ObjectAnimator.ofFloat(mCurrentRect, "top", mCurrentRect.top, mCurrentRect.top-translateY);
ObjectAnimator animateBottom = ObjectAnimator.ofFloat(mCurrentRect, "bottom", mCurrentRect.bottom, mCurrentRect.bottom+translateY);
ArgbEvaluator evaluator = new ArgbEvaluator();
ObjectAnimator animateColor = ObjectAnimator.ofObject(this, "color", evaluator, startColor,midColor,endColor);
animateBottom.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//TODO: DEBUG ANIMATOR
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
postInvalidate();
}
});
AnimatorSet rectAnimation = new AnimatorSet();
rectAnimation.playTogether(animateLeft, animateRight, animateTop, animateBottom,animateColor);
rectAnimation.setDuration(1000).start();
invalidate();
}
playNote、playSound generateColorメソッド
//Generates color based on the press x and y.
private int generateColor(float pressx, float pressy){
int Red = (((int) (pressx%255)) << 16) & 0x00FF0000; //Shift red 16-bits and mask out other stuff
int Green = (((int) (pressy%255)) << 8) & 0x0000FF00; //Shift Green 8-bits and mask out other stuff
int Blue = ((int)((pressx+pressy)%255)) & 0x000000FF; //Mask out anything not blue.
return 0xFF000000 | Red | Green | Blue; //0xFF000000 for 100% Alpha. Bitwise OR everything together.
}
private void playSound(String noun){
Resources res = context.getResources();
int resID = res.getIdentifier(noun, "raw", context.getPackageName());
MediaPlayer mediaPlayer = MediaPlayer.create(context,resID);
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
}
private void playNote(float pressx, float pressy, String note){
colorPaint=new Paint();
colorPaint.setStyle(Paint.Style.STROKE);
colorPaint.setStrokeWidth(10);
colorPaint.setColor(generateColor(pressx,pressy));
float translateX = 50.0f;
float translateY = 50.0f;
Random rand = new Random(10000);
int xr = rand.nextInt();
int yr = rand.nextInt();
int startColor = generateColor(pressx,pressy);
int midColor = generateColor(pressx+rand.nextInt(),pressy+rand.nextInt());
int endColor = generateColor(pressx+xr,pressy+yr);
mCurrentRect = new AnimatableRectF(pressx-50,pressy-50,pressx+50,pressy+50);
debugx=pressx;
playAnimation(startColor,midColor,endColor, translateX, translateY);
playSound(note);
}
ありがとうございます!
が見えます。 mCurrentRect = new AnimatableRectF(pressx-50、pressy-50、pressx + 50、pressy + 50); 描画が開始され、別のサウンドが再生されると、次のオブジェクト(onDraw()が再び呼び出される)の描画が開始されます。それはあなたが最後のものだけを見ている理由を説明することができます。 – WiseGuy
しかし、rectリストを配列リストに格納してそれらから描画すると、すべての矩形を一度に描画するときに、最後まで描画されません。 onDraw自体がループ内で呼び出されることは決してないようです。なぜか、私はplayAnimationメソッドでinvalidate()を呼び出すため、なぜそうは思わないのでしょうか。 – JohnDoe