4

回転するだけのビットマップを持つカスタムProgressBarを作成しています。View.invalidateを使用すると、FPSが途切れます。deltaTimeは40回以上増加します。ロジックとレンダリングはほとんど瞬時に行われますが、invalidate呼び出しはそれを遅くします。だから私はSurfaceViewを試していますが、問題は以前に他のビューでSurfaceViewをアセンブルする際に問題が発生したため、使用したくないということです。SurfaceViewとView.invalidateに代わるものはありますか、それとも私はそれらに固執していますか?

編集:

さらに明確にするために、中間のProgressBarであるカスタムビューを作成しています。つまり、ビューはプログレスバーです。また、現在何もダウンロードしていません。ビューの最大FPSを取得しようとしているだけです。いくつかのコード:

MyProgressBar extends View implements Runnable

そしてrun()

calculateNewRotation();
invalidate();
post(this);

ここでcalculateNewRotation()

long now = SystemClock.uptimeMillis();
int deltaTime = (int) (now - mLastRender);
mLastRender = now;
mSpinRotation += deltaTime * SPIN_SPEED_PER_MILLISECOND_CLOCKWISE;

Post(this)はMyProgressBarを参照し、私が別の言い方をするまで、それは永遠にループします。

私のonDraw()で

mCamera.save();
mCamera.rotateZ(mSpinRotation);
mCamera.getMatrix(mMatrix);
mCamera.restore();

mMatrix.preTranslate(-mTranslatePivotX, -mTranslatePivotY);
mMatrix.postTranslate(mTranslatePivotX + mCenterX, mTranslatePivotY + mCenterY);

canvas.drawBitmap(mSpinBitmap, mMatrix, mSpinBitmapPaint);

calculateNewRotation()の時間=1ミリ秒。

onDraw()の時間=1ミリ秒。

問題は、全体の時間が40ミリ秒を超えることが多いことです。私の解決策はSurfaceViewを使用することですが、表面が透明なピクセルで描画されたビューを使用して、下にある表面が代わりに表示されるようにするというアイデアは好きではありません。私が探しているのは、いつでも、できれば16ミリ秒ごとに60FPSを取得するためにキャンバスを取得できるビューです。さて、そのような見方はありますか?

4

2 に答える 2

1

UI スレッドで長い操作 (通常、プログレス バーが必要な理由) を実行していますか? 別のスレッドまたは非同期タスクが長い操作を処理している間、UI スレッドは進行状況バーを更新する必要があります。

于 2012-11-14T12:30:21.400 に答える
0

最後に行ったのは、画像を描画したときに回転値を1ずつ更新することでした。高速電話と低速電話では滑らかに見えますが、速度は異なります。速い電話では毎秒60フレーム、つまり毎秒60度を描画する可能性がありますが、遅い電話では毎秒10フレームで、スピンは毎秒10度になります。つまり、最終的には、同じ速度で回転させたいのか、見栄えを良くしたいのかということです。後者を選択します。

編集

1秒あたりの最大フレーム数を入れることができると思います。そうすれば、高速の電話が抑制され、高速の電話と小型の電話のギャップが小さくなります。

于 2012-11-14T14:33:23.643 に答える