0

ProgressBar を持つアクティビティがあります。このバーは、ゲーム レベルでの経過時間を表示するために使用されます。

このバーと TextView を 100 ミリ秒ごとに呼び出される CountdownTimer で更新しています。問題は、setProgress を呼び出すたびに、invalidate() が発生し、UI 全体が再描画されるように見えることです。ProgressBar が更新される行を削除すると、残り時間を示す TextView の setText でさえ、すべて正常に動作します。

これは私にとって問題です。これは、必要なときにのみ再描画する必要があるカスタム ビュー、またはパフォーマンスに影響を与えるため、少なくとも数回は再描画する必要があるためです。

これは私のコードの一部です:

private CountDownTimer timer;
private long ttime;
private long ctime;

private ProgressBar bar;
private TextView clock;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    startTimer(500);
    ...
}

@Override
protected void onResume() {
    super.onResume();
    if(!checkFlags()){
        startTimer(500);
    } 
}

@Override
protected void onPause() {
    super.onPause();
    if(!checkFlags()){
        timer.cancel();
    }
}

private void startTimer(long delay){
    timer = new CountDownTimer(ctime,100){
        public void onTick(long millisUntilFinished){
            ctime = millisUntilFinished;
            clock.setText(formatTime(millisUntilFinished));
            bar.setProgress((int) (1000 - ((ctime * 1000)/ttime)));
        }
        
        public void onFinish(){
            clock.setText("00:00");
            gameOver(false);
        }
    };
    
    if(delay > 0){
        Handler handler = new Handler(); 
        handler.postDelayed(new Runnable(){
            public void run(){
                timer.start();
            }
        },delay);
    }else{
        timer.start();
    }
}

ProgressBar が UI のすべての要素に対してこの onDraw 呼び出しを発生させないようにするにはどうすればよいですか?

4

1 に答える 1

0

Android SDK の「sources/android-18/android/widget/ProgressBar.java」によると、setProgress() を呼び出すと、invalidate() が呼び出されます。

private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
        boolean callBackToApp) {
    float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
    final Drawable d = mCurrentDrawable;
    if (d != null) {
        Drawable progressDrawable = null;

        if (d instanceof LayerDrawable) {
            progressDrawable = ((LayerDrawable) d).findDrawableByLayerId(id);
            if (progressDrawable != null && canResolveLayoutDirection()) {
                progressDrawable.setLayoutDirection(getLayoutDirection());
            }
        }

        final int level = (int) (scale * MAX_LEVEL);
        (progressDrawable != null ? progressDrawable : d).setLevel(level);
    } else {
>>>     invalidate();
    }

    if (callBackToApp && id == R.id.progress) {
        onProgressRefresh(scale, fromUser);
    }
}

setProgressDrawable()を使用してみてください。その場合、invalidate() は呼び出されないようです。

于 2013-09-12T18:56:00.050 に答える