ここで 1 回か 2 回対処された問題についてお聞きしたいのですが、数日前に直面した問題を解決するのに役立つ情報は見つかりませんでした。
キャンバスを使用して Android 用のライブ壁紙を作成したい - OpenGL を必要とするほどグラフィカルに複雑ではありません。簡単にするために、無地の背景と 2 つの小さな長方形で構成されていると仮定します。描画は 3 つの段階で構成されます (シングル スレッド)。
- backgroundDraw() はキャンバス全体のロックを要求し、単色で描画します
- draw1() は部分的な (Rect r1) ロックを要求し、ロックされた四角形にのみ描画します
- draw2() は部分的な (Rect r2) ロックを要求し、ロックされた四角形にのみ描画します
複数の Android バージョン (エミュレーターとデバイスの両方) でテストしました: 2.1、2.2、2.3.3。後者でのみ正常に動作しているようです (ここ: http://home.elka.pw.edu.pl/~pgawron/include/Android/android_233.jpg )。以前の Android バージョンでは、SurfaceHolder.lockCanvas(Rect dirty) resizes(!) dirty がパラメーターとしてフルスクリーンのサイズに渡され、それを使用してさらに描画すると、画面全体に描画されます (ここでは: http://home.elka.pw.edu .pl/~pgawron/include/Android/android_22.jpg )。実際、各長方形がどのように正しく描画されていないか (全画面表示) を確認できます。画面全体の色が非常に速く変化します。
残念ながら、Google は lockCanvas(Rect dirty) の適切な使用例を見つけることができませんでした。以下に、テスト目的で使用される完全で唯一のクラスを添付します。Full Eclipse プロジェクトは、提供されたスクリーンショットが配置されている場所からアクセスできます。
誰かが最終的に私を助けてコードを修正できれば、非常に感謝しています(問題が私のコードにある場合のみ)。本当に無駄な時間を過ごしました。
ブラジル、
ペトレリ
package sec.polishcode.test;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.SystemClock;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;
public class TestLiveWallpaper extends WallpaperService{
@Override
public Engine onCreateEngine() {
return new MyEngine();
}
class MyEngine extends Engine implements SurfaceHolder.Callback {
private final String LOGTAG = MyEngine.class.getSimpleName();
private Paint backgroundPaint = new Paint();
private Paint mPaint1 = new Paint();
private Paint mPaint2 = new Paint();
private long lastVisibilityOnChange;
private final Rect r1 = new Rect(20, 20, 60, 280);
private final Rect r2 = new Rect(70, 20, 110, 280);
public MyEngine() {
getSurfaceHolder().addCallback(this);
backgroundPaint.setColor(Color.YELLOW);
mPaint1.setColor(Color.LTGRAY);
mPaint2.setColor(Color.MAGENTA);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
drawSurface();
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.i(LOGTAG, "surfaceCreated");
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.i(LOGTAG, "surfaceDestroyed");
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
}
@Override
public void onVisibilityChanged(boolean visible) {
if (!visible)
return;
lastVisibilityOnChange = SystemClock.elapsedRealtime();
drawSurface();
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
float yStep, int xPixels, int yPixels) {
if (SystemClock.elapsedRealtime() - lastVisibilityOnChange > 30)
return;
Log.i(LOGTAG, "onOffsetsChanged filtered");
drawSurface();
}
private void drawSurface() {
backgroundDraw();
draw1();
draw2();
}
private void backgroundDraw() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
c.drawRect(holder.getSurfaceFrame(), backgroundPaint);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
private void draw1() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas(r1);
if (c != null) {
c.drawRect(r1, mPaint1);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
private void draw2() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas(r2);
if (c != null) {
c.drawRect(r2, mPaint2);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
}
}